@agent-os-lab/agent-game-sdk 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -5
- package/USAGE.md +45 -7
- package/package.json +1 -1
- package/src/office/core/types.ts +7 -0
- package/src/office/index.ts +1 -0
- package/src/office/layout/config.ts +76 -0
- package/src/office/layout/index.ts +2 -0
- package/src/office/layout/resolver.ts +978 -0
- package/src/office/mount.ts +6 -0
- package/src/office/react/AgentGameOfficeView.ts +25 -1
- package/src/office/renderers/three/agent-body-instancing.ts +1 -0
- package/src/office/renderers/three/agent-effect-instancing.ts +1 -0
- package/src/office/renderers/three/agent-layout.ts +12 -56
- package/src/office/renderers/three/mount.ts +8 -6
- package/src/office/renderers/three/scene.ts +256 -84
- package/src/runtime-client.ts +10 -0
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
2
|
import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
|
3
|
+
import type {
|
|
4
|
+
ResolvedOfficeComponentInstance,
|
|
5
|
+
ResolvedOfficeLayout,
|
|
6
|
+
} from "../../layout";
|
|
3
7
|
|
|
4
8
|
export const OFFICE_LAYOUT_SCALE = 1.2;
|
|
5
9
|
const OFFICE_FLOOR_CENTER_X = 16;
|
|
@@ -19,12 +23,15 @@ const DESK_TEMPLATE = [
|
|
|
19
23
|
{ seat: { x: scaleOfficeX(-12), z: scaleOfficeZ(-6.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(-12), z: scaleOfficeZ(-8) } },
|
|
20
24
|
{ seat: { x: scaleOfficeX(-7), z: scaleOfficeZ(-6.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(-7), z: scaleOfficeZ(-8) } },
|
|
21
25
|
{ seat: { x: scaleOfficeX(-2), z: scaleOfficeZ(-6.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(-2), z: scaleOfficeZ(-8) } },
|
|
26
|
+
{ seat: { x: scaleOfficeX(3), z: scaleOfficeZ(-6.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(3), z: scaleOfficeZ(-8) } },
|
|
22
27
|
{ seat: { x: scaleOfficeX(-12), z: scaleOfficeZ(-1.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(-12), z: scaleOfficeZ(-3) } },
|
|
23
28
|
{ seat: { x: scaleOfficeX(-7), z: scaleOfficeZ(-1.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(-7), z: scaleOfficeZ(-3) } },
|
|
24
29
|
{ seat: { x: scaleOfficeX(-2), z: scaleOfficeZ(-1.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(-2), z: scaleOfficeZ(-3) } },
|
|
30
|
+
{ seat: { x: scaleOfficeX(3), z: scaleOfficeZ(-1.2) }, rotation: Math.PI, desk: { x: scaleOfficeX(3), z: scaleOfficeZ(-3) } },
|
|
25
31
|
{ seat: { x: scaleOfficeX(-12), z: scaleOfficeZ(3.8) }, rotation: Math.PI, desk: { x: scaleOfficeX(-12), z: scaleOfficeZ(2) } },
|
|
26
32
|
{ seat: { x: scaleOfficeX(-7), z: scaleOfficeZ(3.8) }, rotation: Math.PI, desk: { x: scaleOfficeX(-7), z: scaleOfficeZ(2) } },
|
|
27
33
|
{ seat: { x: scaleOfficeX(-2), z: scaleOfficeZ(3.8) }, rotation: Math.PI, desk: { x: scaleOfficeX(-2), z: scaleOfficeZ(2) } },
|
|
34
|
+
{ seat: { x: scaleOfficeX(3), z: scaleOfficeZ(3.8) }, rotation: Math.PI, desk: { x: scaleOfficeX(3), z: scaleOfficeZ(2) } },
|
|
28
35
|
] as const;
|
|
29
36
|
export const DESK_SEATS = DESK_TEMPLATE.map((slot) => slot.seat) as ReadonlyArray<{ x: number; z: number }>;
|
|
30
37
|
export const MEETING_ROOMS = [
|
|
@@ -101,6 +108,12 @@ export type OfficeFurniturePlan = {
|
|
|
101
108
|
waterDispensers: number;
|
|
102
109
|
teaBars: number;
|
|
103
110
|
sofas: number;
|
|
111
|
+
treadmills: number;
|
|
112
|
+
stationaryBikes: number;
|
|
113
|
+
dumbbellRacks: number;
|
|
114
|
+
weightBenches: number;
|
|
115
|
+
yogaMats: number;
|
|
116
|
+
gymMirrors: number;
|
|
104
117
|
coffeeTables: number;
|
|
105
118
|
reviewStations: number;
|
|
106
119
|
zonePads: number;
|
|
@@ -108,11 +121,11 @@ export type OfficeFurniturePlan = {
|
|
|
108
121
|
|
|
109
122
|
export function createOfficeFurniturePlan(): OfficeFurniturePlan {
|
|
110
123
|
return {
|
|
111
|
-
desks:
|
|
112
|
-
deskChairs:
|
|
113
|
-
deskChairBases:
|
|
114
|
-
deskChairCasters:
|
|
115
|
-
monitors:
|
|
124
|
+
desks: 12,
|
|
125
|
+
deskChairs: 12,
|
|
126
|
+
deskChairBases: 12,
|
|
127
|
+
deskChairCasters: 60,
|
|
128
|
+
monitors: 12,
|
|
116
129
|
meetingTables: 3,
|
|
117
130
|
meetingTableLegs: 18,
|
|
118
131
|
meetingChairs: 29,
|
|
@@ -128,6 +141,12 @@ export function createOfficeFurniturePlan(): OfficeFurniturePlan {
|
|
|
128
141
|
waterDispensers: 1,
|
|
129
142
|
teaBars: 1,
|
|
130
143
|
sofas: 1,
|
|
144
|
+
treadmills: 2,
|
|
145
|
+
stationaryBikes: 1,
|
|
146
|
+
dumbbellRacks: 1,
|
|
147
|
+
weightBenches: 1,
|
|
148
|
+
yogaMats: 2,
|
|
149
|
+
gymMirrors: 1,
|
|
131
150
|
coffeeTables: 0,
|
|
132
151
|
reviewStations: 0,
|
|
133
152
|
zonePads: 2,
|
|
@@ -142,21 +161,16 @@ export function addLights(scene: THREE.Scene): void {
|
|
|
142
161
|
scene.add(directional);
|
|
143
162
|
}
|
|
144
163
|
|
|
145
|
-
export function buildOfficeScene(scene: THREE.Scene): void {
|
|
146
|
-
buildOfficeBaseFloors(scene);
|
|
147
|
-
buildOfficeWalls(scene);
|
|
164
|
+
export function buildOfficeScene(scene: THREE.Scene, layout: ResolvedOfficeLayout): void {
|
|
165
|
+
buildOfficeBaseFloors(scene, layout);
|
|
166
|
+
buildOfficeWalls(scene, layout);
|
|
148
167
|
|
|
149
168
|
const batcher = new BoxInstanceBatcher(scene);
|
|
150
169
|
const transparentCache = new TransparentBoxCache();
|
|
151
170
|
activeBoxBatcher = batcher;
|
|
152
171
|
activeTransparentBoxCache = transparentCache;
|
|
153
172
|
try {
|
|
154
|
-
|
|
155
|
-
buildDeskCluster(scene);
|
|
156
|
-
buildMeetingRoom(scene);
|
|
157
|
-
buildLargeMeetingRoom(scene);
|
|
158
|
-
buildLounge(scene);
|
|
159
|
-
buildTeaBar(scene);
|
|
173
|
+
layout.components.forEach((component) => renderOfficeComponent(scene, component));
|
|
160
174
|
} finally {
|
|
161
175
|
activeBoxBatcher = undefined;
|
|
162
176
|
activeTransparentBoxCache = undefined;
|
|
@@ -280,32 +294,30 @@ class TransparentBoxCache {
|
|
|
280
294
|
|
|
281
295
|
let activeTransparentBoxCache: TransparentBoxCache | undefined;
|
|
282
296
|
|
|
283
|
-
function buildOfficeBaseFloors(scene: THREE.Scene) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
addBaseFloor(scene, 0xe5e7eb, (floorMinX + officeSplitX) / 2, officeSplitX - floorMinX, OFFICE_FLOOR_DEPTH);
|
|
288
|
-
addBaseFloor(scene, 0xdbe4ec, (officeSplitX + floorMaxX) / 2, floorMaxX - officeSplitX, OFFICE_FLOOR_DEPTH);
|
|
297
|
+
function buildOfficeBaseFloors(scene: THREE.Scene, layout: ResolvedOfficeLayout) {
|
|
298
|
+
layout.scene.floorTiles.forEach((tile) => {
|
|
299
|
+
addBaseFloor(scene, tile.color, tile.x, tile.z, tile.width, tile.depth);
|
|
300
|
+
});
|
|
289
301
|
}
|
|
290
302
|
|
|
291
|
-
function addBaseFloor(scene: THREE.Scene, color: number, x: number, width: number, depth: number) {
|
|
303
|
+
function addBaseFloor(scene: THREE.Scene, color: number, x: number, z: number, width: number, depth: number) {
|
|
292
304
|
const floor = new THREE.Mesh(
|
|
293
305
|
new THREE.BoxGeometry(width, 0.2, depth),
|
|
294
306
|
new THREE.MeshLambertMaterial({ color }),
|
|
295
307
|
);
|
|
296
308
|
floor.receiveShadow = true;
|
|
297
|
-
floor.position.set(x, -0.1,
|
|
309
|
+
floor.position.set(x, -0.1, z);
|
|
298
310
|
scene.add(floor);
|
|
299
|
-
addGridFloorLines(scene, x, width, depth);
|
|
311
|
+
addGridFloorLines(scene, x, z, width, depth);
|
|
300
312
|
}
|
|
301
313
|
|
|
302
|
-
function addGridFloorLines(scene: THREE.Scene, x: number, width: number, depth: number) {
|
|
314
|
+
function addGridFloorLines(scene: THREE.Scene, x: number, z: number, width: number, depth: number) {
|
|
303
315
|
const geometry = new THREE.BufferGeometry();
|
|
304
316
|
const positions: number[] = [];
|
|
305
317
|
const minX = x - width / 2;
|
|
306
318
|
const maxX = x + width / 2;
|
|
307
|
-
const minZ = -depth / 2;
|
|
308
|
-
const maxZ = depth / 2;
|
|
319
|
+
const minZ = z - depth / 2;
|
|
320
|
+
const maxZ = z + depth / 2;
|
|
309
321
|
|
|
310
322
|
for (let lineX = minX; lineX <= maxX + 0.001; lineX += OFFICE_FLOOR_TILE_SIZE) {
|
|
311
323
|
positions.push(lineX, 0.012, minZ, lineX, 0.012, maxZ);
|
|
@@ -323,17 +335,25 @@ function addGridFloorLines(scene: THREE.Scene, x: number, width: number, depth:
|
|
|
323
335
|
scene.add(lines);
|
|
324
336
|
}
|
|
325
337
|
|
|
326
|
-
function buildOfficeWalls(scene: THREE.Scene) {
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
338
|
+
function buildOfficeWalls(scene: THREE.Scene, layout: ResolvedOfficeLayout) {
|
|
339
|
+
const materialCache = new Map<number, THREE.MeshLambertMaterial>();
|
|
340
|
+
layout.scene.walls.forEach((wall) => {
|
|
341
|
+
const material = materialCache.get(wall.color) ?? (() => {
|
|
342
|
+
const created = new THREE.MeshLambertMaterial({ color: wall.color });
|
|
343
|
+
materialCache.set(wall.color, created);
|
|
344
|
+
return created;
|
|
345
|
+
})();
|
|
346
|
+
addOfficeWallBox(
|
|
347
|
+
scene,
|
|
348
|
+
wall.width,
|
|
349
|
+
wall.height,
|
|
350
|
+
wall.depth,
|
|
351
|
+
wall.x,
|
|
352
|
+
wall.height / 2,
|
|
353
|
+
wall.z,
|
|
354
|
+
material,
|
|
355
|
+
);
|
|
356
|
+
});
|
|
337
357
|
}
|
|
338
358
|
|
|
339
359
|
function addOfficeWallBox(
|
|
@@ -378,6 +398,23 @@ function addWallWhiteboard(scene: THREE.Scene, x: number, wallZ: number, rotatio
|
|
|
378
398
|
addLocalBox(scene, 0x64748b, 1.2, 0.06, 0.05, x, wallZ, -0.5, 1.02, offsets.trayZ, rotation);
|
|
379
399
|
}
|
|
380
400
|
|
|
401
|
+
function addWallWindow(
|
|
402
|
+
scene: THREE.Scene,
|
|
403
|
+
x: number,
|
|
404
|
+
wallZ: number,
|
|
405
|
+
rotation: number,
|
|
406
|
+
faceDirection: -1 | 1,
|
|
407
|
+
width = 3.1,
|
|
408
|
+
height = 1.25,
|
|
409
|
+
) {
|
|
410
|
+
const frameZ = 0.08 * faceDirection;
|
|
411
|
+
const paneZ = 0.13 * faceDirection;
|
|
412
|
+
addLocalBox(scene, 0x64748b, width + 0.18, height + 0.18, 0.06, x, wallZ, 0, 1.65, frameZ, rotation);
|
|
413
|
+
addLocalBox(scene, 0x9bdaf2, width, height, 0.04, x, wallZ, 0, 1.65, paneZ, rotation);
|
|
414
|
+
addLocalBox(scene, 0xe0f2fe, 0.08, height, 0.05, x, wallZ, 0, 1.65, paneZ + 0.01 * faceDirection, rotation);
|
|
415
|
+
addLocalBox(scene, 0xe0f2fe, width, 0.08, 0.05, x, wallZ, 0, 1.65, paneZ + 0.012 * faceDirection, rotation);
|
|
416
|
+
}
|
|
417
|
+
|
|
381
418
|
function addStickyNoteBoard(scene: THREE.Scene, x: number, z: number) {
|
|
382
419
|
addBox(scene, 0xb87333, 3, 1.5, 0.08, x, 1.5, z - 0.04);
|
|
383
420
|
addBox(scene, 0xd4a76a, 2.8, 1.3, 0.05, x, 1.5, z + 0.02);
|
|
@@ -414,7 +451,7 @@ function buildDeskCluster(scene: THREE.Scene) {
|
|
|
414
451
|
|
|
415
452
|
function buildMeetingRoom(scene: THREE.Scene) {
|
|
416
453
|
MEETING_ROOMS.forEach((room, roomIndex) => {
|
|
417
|
-
addMeetingGlassRoom(scene, roomIndex);
|
|
454
|
+
addMeetingGlassRoom(scene, roomIndex, room.center.x, room.center.z, 8 * OFFICE_LAYOUT_SCALE);
|
|
418
455
|
addMeetingTable(scene, room.center.x, room.center.z, room.topColor, room.legColor, room.tableDepth);
|
|
419
456
|
room.seats.forEach((seat) => addOfficeChair(scene, seat.x, seat.z, seat.rotation));
|
|
420
457
|
});
|
|
@@ -450,6 +487,106 @@ function buildTeaBar(scene: THREE.Scene) {
|
|
|
450
487
|
addWaterDispenser(scene, scaleOfficeX(-16.9), scaleOfficeZ(10.4));
|
|
451
488
|
}
|
|
452
489
|
|
|
490
|
+
function renderOfficeComponent(scene: THREE.Scene, component: ResolvedOfficeComponentInstance) {
|
|
491
|
+
const { x, z } = component.position;
|
|
492
|
+
const rotation = component.rotation ?? 0;
|
|
493
|
+
switch (component.kind) {
|
|
494
|
+
case "desk":
|
|
495
|
+
addDesk(scene, x, z);
|
|
496
|
+
return;
|
|
497
|
+
case "officeChair":
|
|
498
|
+
addOfficeChair(scene, x, z, rotation);
|
|
499
|
+
return;
|
|
500
|
+
case "monitor":
|
|
501
|
+
addMonitor(scene, x, z);
|
|
502
|
+
return;
|
|
503
|
+
case "meetingTable":
|
|
504
|
+
addMeetingTable(
|
|
505
|
+
scene,
|
|
506
|
+
x,
|
|
507
|
+
z,
|
|
508
|
+
component.props?.topColor,
|
|
509
|
+
component.props?.legColor,
|
|
510
|
+
component.props?.depth,
|
|
511
|
+
);
|
|
512
|
+
return;
|
|
513
|
+
case "meetingGlassRoom":
|
|
514
|
+
addMeetingGlassRoom(
|
|
515
|
+
scene,
|
|
516
|
+
component.props?.roomIndex ?? 0,
|
|
517
|
+
x,
|
|
518
|
+
z,
|
|
519
|
+
component.props?.depth ?? 8 * OFFICE_LAYOUT_SCALE,
|
|
520
|
+
component.props?.omitGlassSide ?? component.props?.wallSide,
|
|
521
|
+
component.props?.whiteboardSide ?? component.props?.wallSide,
|
|
522
|
+
);
|
|
523
|
+
return;
|
|
524
|
+
case "largeMeetingTable":
|
|
525
|
+
addLargeMeetingTable(scene, x, z);
|
|
526
|
+
return;
|
|
527
|
+
case "tableCup":
|
|
528
|
+
addTableCup(scene, x, z);
|
|
529
|
+
return;
|
|
530
|
+
case "dividerGlass":
|
|
531
|
+
addOfficeDividerGlass(scene);
|
|
532
|
+
return;
|
|
533
|
+
case "wallWhiteboard":
|
|
534
|
+
addWallWhiteboard(scene, x, z, rotation, component.props?.faceDirection ?? 1);
|
|
535
|
+
return;
|
|
536
|
+
case "wallWindow":
|
|
537
|
+
addWallWindow(scene, x, z, rotation, component.props?.faceDirection ?? 1, component.props?.width, component.props?.height);
|
|
538
|
+
return;
|
|
539
|
+
case "stickyNoteBoard":
|
|
540
|
+
addStickyNoteBoard(scene, x, z);
|
|
541
|
+
return;
|
|
542
|
+
case "wallClock":
|
|
543
|
+
addWallClock(scene, x, z);
|
|
544
|
+
return;
|
|
545
|
+
case "sofa":
|
|
546
|
+
addSofa(scene, x, z);
|
|
547
|
+
return;
|
|
548
|
+
case "loungeSideTable":
|
|
549
|
+
addLoungeSideTable(scene, x, z);
|
|
550
|
+
return;
|
|
551
|
+
case "bookcase":
|
|
552
|
+
addBookcase(scene, x, z);
|
|
553
|
+
return;
|
|
554
|
+
case "teaCounter":
|
|
555
|
+
addTeaCounter(scene, x, z);
|
|
556
|
+
return;
|
|
557
|
+
case "waterDispenser":
|
|
558
|
+
addWaterDispenser(scene, x, z);
|
|
559
|
+
return;
|
|
560
|
+
case "presentationBoard":
|
|
561
|
+
addPresentationBoard(scene, x, z, component.props?.screenColor, rotation);
|
|
562
|
+
return;
|
|
563
|
+
case "mobileDisplayStand":
|
|
564
|
+
addMobileDisplayStand(scene, x, z, rotation);
|
|
565
|
+
return;
|
|
566
|
+
case "treadmill":
|
|
567
|
+
addTreadmill(scene, x, z, rotation);
|
|
568
|
+
return;
|
|
569
|
+
case "stationaryBike":
|
|
570
|
+
addStationaryBike(scene, x, z, rotation);
|
|
571
|
+
return;
|
|
572
|
+
case "dumbbellRack":
|
|
573
|
+
addDumbbellRack(scene, x, z, rotation);
|
|
574
|
+
return;
|
|
575
|
+
case "weightBench":
|
|
576
|
+
addWeightBench(scene, x, z, rotation);
|
|
577
|
+
return;
|
|
578
|
+
case "yogaMat":
|
|
579
|
+
addYogaMat(scene, x, z, rotation);
|
|
580
|
+
return;
|
|
581
|
+
case "gymMirror":
|
|
582
|
+
addGymMirror(scene, x, z, rotation, component.props?.width, component.props?.faceDirection ?? 1);
|
|
583
|
+
return;
|
|
584
|
+
case "glassWall":
|
|
585
|
+
case "glassDoor":
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
453
590
|
function addDesk(scene: THREE.Scene, x: number, z: number) {
|
|
454
591
|
addBox(scene, 0xd2b48c, 3, 0.15, 1.8, x, 1.5, z);
|
|
455
592
|
addBox(scene, 0x8b7355, 0.15, 1.5, 0.15, x - 1.3, 0.75, z - 0.7);
|
|
@@ -506,55 +643,39 @@ function addMeetingTable(
|
|
|
506
643
|
addBox(scene, legColor, 0.2, 1.5, 0.2, x + 2.2, 0.75, z + legZ);
|
|
507
644
|
}
|
|
508
645
|
|
|
509
|
-
function addMeetingGlassRoom(
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
646
|
+
function addMeetingGlassRoom(
|
|
647
|
+
scene: THREE.Scene,
|
|
648
|
+
roomIndex: number,
|
|
649
|
+
x: number,
|
|
650
|
+
z: number,
|
|
651
|
+
depth: number,
|
|
652
|
+
omitGlassSide?: "north" | "south",
|
|
653
|
+
whiteboardSide?: "north" | "south",
|
|
654
|
+
) {
|
|
655
|
+
const width = 11.7 * OFFICE_LAYOUT_SCALE;
|
|
656
|
+
const westX = x - width / 2;
|
|
657
|
+
const eastX = x + width / 2;
|
|
658
|
+
const northZ = z - depth / 2;
|
|
659
|
+
const southZ = z + depth / 2;
|
|
660
|
+
|
|
661
|
+
addGlassWallWithDoor(scene, roomIndex, westX, z, depth, roomIndex === 0 ? 1.9 : 1.6, 0.25);
|
|
662
|
+
addTransparentBox(scene, 0x88ccee, 0.08, 2.5, depth, eastX, 1.25, z, 0.15, `meetingGlassRoom:${roomIndex}:east`);
|
|
663
|
+
if (omitGlassSide !== "north") {
|
|
664
|
+
addTransparentBox(scene, 0x88ccee, width, 2.5, 0.08, x, 1.25, northZ, 0.2, `meetingGlassRoom:${roomIndex}:north`);
|
|
665
|
+
}
|
|
666
|
+
if (omitGlassSide !== "south") {
|
|
667
|
+
addTransparentBox(scene, 0x88ccee, width, 2.5, 0.08, x, 1.25, southZ, 0.2, `meetingGlassRoom:${roomIndex}:south`);
|
|
528
668
|
}
|
|
529
669
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
scaleOfficeX(10.5),
|
|
534
|
-
(northWallFaceZ + scaleOfficeZ(sharedWallZ)) / 2,
|
|
535
|
-
scaleOfficeZ(sharedWallZ) - northWallFaceZ,
|
|
536
|
-
1.6,
|
|
537
|
-
0.25,
|
|
538
|
-
);
|
|
539
|
-
addTransparentBox(scene, 0x88ccee, 11.7 * OFFICE_LAYOUT_SCALE, 2.5, 0.08, scaleOfficeX(16.35), 1.25, northWallFaceZ, 0.2);
|
|
540
|
-
addTransparentBox(
|
|
541
|
-
scene,
|
|
542
|
-
0x88ccee,
|
|
543
|
-
0.08,
|
|
544
|
-
2.5,
|
|
545
|
-
scaleOfficeZ(-9.3) - northWallFaceZ,
|
|
546
|
-
scaleOfficeX(22.2),
|
|
547
|
-
1.25,
|
|
548
|
-
(northWallFaceZ + scaleOfficeZ(-9.3)) / 2,
|
|
549
|
-
0.15,
|
|
550
|
-
);
|
|
551
|
-
addMeetingWhiteboard(scene, scaleOfficeX(16.35), northWallFaceZ, 0);
|
|
670
|
+
const whiteboardWallSide = whiteboardSide ?? "north";
|
|
671
|
+
const whiteboardZ = whiteboardWallSide === "south" ? southZ - 0.28 : northZ + 0.28;
|
|
672
|
+
addMeetingWhiteboard(scene, x, whiteboardZ, whiteboardWallSide === "south" ? Math.PI : 0);
|
|
552
673
|
[
|
|
553
|
-
[
|
|
554
|
-
[
|
|
555
|
-
[
|
|
556
|
-
[
|
|
557
|
-
].forEach(([
|
|
674
|
+
[westX, northZ],
|
|
675
|
+
[westX, southZ],
|
|
676
|
+
[eastX, northZ],
|
|
677
|
+
[eastX, southZ],
|
|
678
|
+
].forEach(([postX, postZ]) => addBox(scene, 0xcccccc, 0.15, 2.5, 0.15, postX, 1.25, postZ));
|
|
558
679
|
}
|
|
559
680
|
|
|
560
681
|
function addOfficeDividerGlass(scene: THREE.Scene) {
|
|
@@ -704,6 +825,57 @@ function addWaterDispenser(scene: THREE.Scene, x: number, z: number) {
|
|
|
704
825
|
addBox(scene, 0xf8fafc, 0.2, 0.22, 0.2, x + 0.25, 0.42, z - 0.16);
|
|
705
826
|
}
|
|
706
827
|
|
|
828
|
+
function addTreadmill(scene: THREE.Scene, x: number, z: number, rotation = 0) {
|
|
829
|
+
addLocalBox(scene, 0x111827, 1.45, 0.18, 3.4, x, z, 0, 0.18, 0, rotation);
|
|
830
|
+
addLocalBox(scene, 0x475569, 1.18, 0.06, 2.85, x, z, 0, 0.32, 0.06, rotation);
|
|
831
|
+
addLocalBox(scene, 0x64748b, 0.12, 1.35, 0.12, x, z, -0.62, 0.92, -1.42, rotation);
|
|
832
|
+
addLocalBox(scene, 0x64748b, 0.12, 1.35, 0.12, x, z, 0.62, 0.92, -1.42, rotation);
|
|
833
|
+
addLocalBox(scene, 0x0f172a, 1.1, 0.55, 0.08, x, z, 0, 1.5, -1.55, rotation);
|
|
834
|
+
addLocalBox(scene, 0x38bdf8, 0.82, 0.36, 0.04, x, z, 0, 1.5, -1.61, rotation);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
function addStationaryBike(scene: THREE.Scene, x: number, z: number, rotation = 0) {
|
|
838
|
+
addLocalBox(scene, 0x334155, 1.1, 0.1, 1.25, x, z, 0, 0.28, 0, rotation);
|
|
839
|
+
addLocalBox(scene, 0x64748b, 0.12, 1.1, 0.12, x, z, 0, 0.85, 0.15, rotation);
|
|
840
|
+
addLocalBox(scene, 0x111827, 0.68, 0.16, 0.55, x, z, 0, 1.38, 0.22, rotation);
|
|
841
|
+
addLocalBox(scene, 0x64748b, 1.1, 0.08, 0.08, x, z, 0, 1.38, -0.42, rotation);
|
|
842
|
+
addLocalBox(scene, 0x0f172a, 0.92, 0.92, 0.08, x, z, 0, 0.62, -0.22, rotation);
|
|
843
|
+
addLocalBox(scene, 0x0f172a, 0.32, 0.32, 0.12, x, z, 0, 0.62, -0.22, rotation);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function addDumbbellRack(scene: THREE.Scene, x: number, z: number, rotation = 0) {
|
|
847
|
+
addLocalBox(scene, 0x475569, 3.2, 0.12, 0.22, x, z, 0, 0.75, 0, rotation);
|
|
848
|
+
addLocalBox(scene, 0x334155, 3.2, 0.12, 0.22, x, z, 0, 0.38, 0.18, rotation);
|
|
849
|
+
for (let index = 0; index < 6; index += 1) {
|
|
850
|
+
const localX = -1.25 + index * 0.5;
|
|
851
|
+
addLocalBox(scene, 0x111827, 0.18, 0.18, 0.18, x, z, localX - 0.08, 0.9, -0.06, rotation);
|
|
852
|
+
addLocalBox(scene, 0x111827, 0.18, 0.18, 0.18, x, z, localX + 0.08, 0.9, -0.06, rotation);
|
|
853
|
+
addLocalBox(scene, 0xe5e7eb, 0.18, 0.06, 0.06, x, z, localX, 0.9, -0.06, rotation);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function addWeightBench(scene: THREE.Scene, x: number, z: number, rotation = 0) {
|
|
858
|
+
addLocalBox(scene, 0x111827, 2.25, 0.18, 0.62, x, z, 0, 0.55, 0, rotation);
|
|
859
|
+
addLocalBox(scene, 0x64748b, 0.12, 0.65, 0.12, x, z, -0.85, 0.26, -0.22, rotation);
|
|
860
|
+
addLocalBox(scene, 0x64748b, 0.12, 0.65, 0.12, x, z, 0.85, 0.26, 0.22, rotation);
|
|
861
|
+
addLocalBox(scene, 0x475569, 2.7, 0.08, 0.08, x, z, 0, 1.25, -0.56, rotation);
|
|
862
|
+
addLocalBox(scene, 0x111827, 0.28, 0.5, 0.5, x, z, -1.48, 1.25, -0.56, rotation);
|
|
863
|
+
addLocalBox(scene, 0x111827, 0.28, 0.5, 0.5, x, z, 1.48, 1.25, -0.56, rotation);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
function addYogaMat(scene: THREE.Scene, x: number, z: number, rotation = 0) {
|
|
867
|
+
addLocalBox(scene, 0x0ea5e9, 1.35, 0.04, 3.05, x, z, 0, 0.04, 0, rotation);
|
|
868
|
+
addLocalBox(scene, 0xbae6fd, 1.05, 0.02, 0.18, x, z, 0, 0.08, -1.18, rotation);
|
|
869
|
+
addLocalBox(scene, 0xbae6fd, 1.05, 0.02, 0.18, x, z, 0, 0.08, 1.18, rotation);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function addGymMirror(scene: THREE.Scene, x: number, z: number, rotation = 0, width = 5.2, faceDirection: -1 | 1 = 1) {
|
|
873
|
+
addLocalBox(scene, 0x64748b, width + 0.18, 1.8, 0.06, x, z, 0, 1.45, 0.07 * faceDirection, rotation);
|
|
874
|
+
addLocalBox(scene, 0xbfefff, width, 1.62, 0.04, x, z, 0, 1.45, 0.12 * faceDirection, rotation);
|
|
875
|
+
addLocalBox(scene, 0xe0f2fe, 0.08, 1.42, 0.05, x, z, -width * 0.28, 1.45, 0.14 * faceDirection, rotation);
|
|
876
|
+
addLocalBox(scene, 0xe0f2fe, 0.08, 1.42, 0.05, x, z, width * 0.18, 1.45, 0.14 * faceDirection, rotation);
|
|
877
|
+
}
|
|
878
|
+
|
|
707
879
|
function addBox(
|
|
708
880
|
scene: THREE.Scene,
|
|
709
881
|
color: number,
|
package/src/runtime-client.ts
CHANGED
|
@@ -59,6 +59,7 @@ export type GameRuntimeConnectionState = "connecting" | "online" | "closed";
|
|
|
59
59
|
export type GameRuntimeSubscription = {
|
|
60
60
|
close: () => void;
|
|
61
61
|
getSocket: () => WebSocket | null;
|
|
62
|
+
refresh: () => void;
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
export type AgentGameRuntimeBrowserClientOptions = {
|
|
@@ -310,6 +311,15 @@ export function subscribeGameRuntime(
|
|
|
310
311
|
}
|
|
311
312
|
|
|
312
313
|
return {
|
|
314
|
+
refresh: () => {
|
|
315
|
+
if (closed || socket.readyState !== WebSocketCtor.OPEN) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
socket.send(JSON.stringify({
|
|
319
|
+
type: "refresh",
|
|
320
|
+
tenantId: options.tenantId,
|
|
321
|
+
}));
|
|
322
|
+
},
|
|
313
323
|
close: () => {
|
|
314
324
|
closed = true;
|
|
315
325
|
clearPingInterval();
|