let-them-talk 5.2.5 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -1
- package/README.md +158 -592
- package/SECURITY.md +3 -3
- package/USAGE.md +151 -0
- package/agent-contracts.js +447 -0
- package/api-agents.js +760 -0
- package/autonomy/decision-v2.js +380 -0
- package/autonomy/watchdog-policy.js +572 -0
- package/cli.js +454 -298
- package/conversation-templates/autonomous-feature.json +83 -22
- package/conversation-templates/code-review.json +69 -21
- package/conversation-templates/debug-squad.json +69 -21
- package/conversation-templates/feature-build.json +69 -21
- package/conversation-templates/research-write.json +69 -21
- package/dashboard.html +3148 -174
- package/dashboard.js +823 -786
- package/data-dir.js +58 -0
- package/docs/architecture/branch-semantics.md +157 -0
- package/docs/architecture/canonical-event-schema.md +88 -0
- package/docs/architecture/markdown-workspace.md +183 -0
- package/docs/architecture/runtime-contract.md +459 -0
- package/docs/architecture/runtime-migration-hardening.md +64 -0
- package/events/hooks.js +154 -0
- package/events/log.js +457 -0
- package/events/replay.js +33 -0
- package/events/schema.js +432 -0
- package/managed-team-integration.js +261 -0
- package/office/agents.js +704 -597
- package/office/animation.js +1 -1
- package/office/assets/arcade-cabinet.js +141 -0
- package/office/assets/archway.js +77 -0
- package/office/assets/bar-counter.js +91 -0
- package/office/assets/bar-stool.js +71 -0
- package/office/assets/beanbag.js +64 -0
- package/office/assets/bench.js +99 -0
- package/office/assets/bollard.js +87 -0
- package/office/assets/cactus.js +100 -0
- package/office/assets/carpet-tile.js +46 -0
- package/office/assets/chair.js +123 -0
- package/office/assets/chandelier.js +107 -0
- package/office/assets/coffee-machine.js +95 -0
- package/office/assets/coffee-table.js +81 -0
- package/office/assets/column.js +95 -0
- package/office/assets/desk-lamp.js +102 -0
- package/office/assets/desk.js +76 -0
- package/office/assets/dining-table.js +105 -0
- package/office/assets/door.js +70 -0
- package/office/assets/dual-monitor.js +72 -0
- package/office/assets/fence.js +76 -0
- package/office/assets/filing-cabinet.js +111 -0
- package/office/assets/floor-lamp.js +69 -0
- package/office/assets/floor-tile.js +54 -0
- package/office/assets/flower-pot.js +76 -0
- package/office/assets/foosball.js +95 -0
- package/office/assets/fridge.js +99 -0
- package/office/assets/gaming-chair.js +154 -0
- package/office/assets/gaming-desk.js +105 -0
- package/office/assets/glass-door.js +72 -0
- package/office/assets/glass-wall.js +64 -0
- package/office/assets/half-wall.js +49 -0
- package/office/assets/hanging-plant.js +112 -0
- package/office/assets/index.js +151 -0
- package/office/assets/indoor-tree.js +90 -0
- package/office/assets/l-sofa.js +153 -0
- package/office/assets/marble-floor.js +64 -0
- package/office/assets/materials.js +40 -0
- package/office/assets/meeting-table.js +88 -0
- package/office/assets/microwave.js +94 -0
- package/office/assets/monitor.js +67 -0
- package/office/assets/neon-strip.js +73 -0
- package/office/assets/painting.js +84 -0
- package/office/assets/palm-tree.js +108 -0
- package/office/assets/pc-tower.js +91 -0
- package/office/assets/pendant-light.js +67 -0
- package/office/assets/ping-pong.js +114 -0
- package/office/assets/plant.js +72 -0
- package/office/assets/planter-box.js +95 -0
- package/office/assets/pool-table.js +94 -0
- package/office/assets/printer.js +113 -0
- package/office/assets/reception-desk.js +133 -0
- package/office/assets/rug.js +78 -0
- package/office/assets/sculpture.js +85 -0
- package/office/assets/server-rack.js +98 -0
- package/office/assets/sink.js +109 -0
- package/office/assets/sofa.js +106 -0
- package/office/assets/speaker.js +83 -0
- package/office/assets/spotlight.js +83 -0
- package/office/assets/street-lamp.js +97 -0
- package/office/assets/trash-can.js +83 -0
- package/office/assets/treadmill.js +126 -0
- package/office/assets/trophy.js +89 -0
- package/office/assets/tv-screen.js +79 -0
- package/office/assets/vase.js +84 -0
- package/office/assets/wall-clock.js +84 -0
- package/office/assets/wall.js +53 -0
- package/office/assets/water-cooler.js +146 -0
- package/office/assets/whiteboard.js +115 -0
- package/office/assets.js +3 -431
- package/office/builder.js +791 -355
- package/office/campus-env.js +1012 -1119
- package/office/environment.js +2 -0
- package/office/gallery.js +997 -0
- package/office/index.js +165 -61
- package/office/navigation.js +173 -152
- package/office/player.js +178 -68
- package/office/robot-character.js +272 -0
- package/office/spectator-camera.js +33 -10
- package/office/state.js +2 -0
- package/office/world-save.js +35 -4
- package/package.json +57 -3
- package/providers/comfyui.js +383 -0
- package/providers/dalle.js +79 -0
- package/providers/gemini.js +181 -0
- package/providers/ollama.js +184 -0
- package/providers/replicate.js +115 -0
- package/providers/zai.js +183 -0
- package/runtime-descriptor.js +270 -0
- package/scripts/check-agent-contract-advisory.js +132 -0
- package/scripts/check-api-agent-parity.js +277 -0
- package/scripts/check-autonomy-v2-decision.js +207 -0
- package/scripts/check-autonomy-v2-execution.js +588 -0
- package/scripts/check-autonomy-v2-watchdog.js +224 -0
- package/scripts/check-branch-fork-snapshot.js +337 -0
- package/scripts/check-branch-isolation.js +787 -0
- package/scripts/check-branch-semantics.js +139 -0
- package/scripts/check-dashboard-control-plane.js +1304 -0
- package/scripts/check-docs-onboarding.js +490 -0
- package/scripts/check-event-schema.js +276 -0
- package/scripts/check-evidence-completion.js +239 -0
- package/scripts/check-invariants.js +992 -0
- package/scripts/check-lifecycle-hooks.js +525 -0
- package/scripts/check-managed-team-integration.js +166 -0
- package/scripts/check-markdown-workspace-export.js +548 -0
- package/scripts/check-markdown-workspace-safety.js +347 -0
- package/scripts/check-markdown-workspace.js +136 -0
- package/scripts/check-message-replay.js +429 -0
- package/scripts/check-migration-hardening.js +300 -0
- package/scripts/check-performance-indexing.js +272 -0
- package/scripts/check-provider-capabilities.js +316 -0
- package/scripts/check-runtime-contract.js +109 -0
- package/scripts/check-session-aware-context.js +172 -0
- package/scripts/check-session-lifecycle.js +210 -0
- package/scripts/export-markdown-workspace.js +84 -0
- package/scripts/fixtures/message-replay/clean.jsonl +2 -0
- package/scripts/fixtures/message-replay/corrupt-correction-payload.jsonl +1 -0
- package/scripts/fixtures/message-replay/corrupt-jsonl.jsonl +1 -0
- package/scripts/fixtures/message-replay/corrupt-payload.jsonl +1 -0
- package/scripts/fixtures/message-replay/out-of-order.jsonl +2 -0
- package/scripts/migrate-legacy-to-canonical.js +201 -0
- package/scripts/run-verification-suite.js +242 -0
- package/scripts/sync-packaged-docs.js +69 -0
- package/server.js +9546 -7214
- package/state/agents.js +161 -0
- package/state/canonical.js +3068 -0
- package/state/dashboard-queries.js +441 -0
- package/state/evidence.js +56 -0
- package/state/io.js +69 -0
- package/state/markdown-workspace.js +951 -0
- package/state/messages.js +669 -0
- package/state/sessions.js +683 -0
- package/state/tasks-workflows.js +92 -0
- package/templates/debate.json +2 -2
- package/templates/managed.json +4 -4
- package/templates/pair.json +2 -2
- package/templates/review.json +2 -2
- package/templates/team.json +3 -3
package/office/animation.js
CHANGED
|
@@ -204,7 +204,7 @@ export function updateAgent(agent, dt, time) {
|
|
|
204
204
|
var sittingTarget = agent.isSitting ? 1 : 0;
|
|
205
205
|
agent.sittingLerp += (sittingTarget - agent.sittingLerp) * Math.min(1, dt * 5);
|
|
206
206
|
|
|
207
|
-
agent.parts.group.position.y = agent.sittingLerp * 0.
|
|
207
|
+
agent.parts.group.position.y = agent.sittingLerp * 0.08;
|
|
208
208
|
var sitHip = -1.5 * agent.sittingLerp;
|
|
209
209
|
agent.parts.leftLeg.rotation.x = agent.parts.leftLeg.rotation.x * (1 - agent.sittingLerp) + sitHip * agent.sittingLerp;
|
|
210
210
|
agent.parts.rightLeg.rotation.x = agent.parts.rightLeg.rotation.x * (1 - agent.sittingLerp) + sitHip * agent.sittingLerp;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'arcade_cabinet',
|
|
6
|
+
name: 'Arcade Cabinet',
|
|
7
|
+
category: 'recreation',
|
|
8
|
+
icon: 'AC',
|
|
9
|
+
gridW: 1, gridD: 1, height: 1.7,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
// Main cabinet body
|
|
14
|
+
var body = new THREE.Mesh(
|
|
15
|
+
new THREE.BoxGeometry(0.70, 1.50, 0.60),
|
|
16
|
+
mat(0x0e1014, { roughness: 0.50, metalness: 0.15 })
|
|
17
|
+
);
|
|
18
|
+
body.position.y = 0.75;
|
|
19
|
+
body.castShadow = true;
|
|
20
|
+
body.receiveShadow = true;
|
|
21
|
+
g.add(body);
|
|
22
|
+
|
|
23
|
+
// Top angled marquee section
|
|
24
|
+
var marquee = new THREE.Mesh(
|
|
25
|
+
new THREE.BoxGeometry(0.70, 0.26, 0.38),
|
|
26
|
+
mat(0x111318, { roughness: 0.45 })
|
|
27
|
+
);
|
|
28
|
+
marquee.position.set(0, 1.63, -0.11);
|
|
29
|
+
marquee.castShadow = true;
|
|
30
|
+
g.add(marquee);
|
|
31
|
+
|
|
32
|
+
// Marquee light (emissive panel)
|
|
33
|
+
var marqueeLit = new THREE.Mesh(
|
|
34
|
+
new THREE.BoxGeometry(0.58, 0.18, 0.01),
|
|
35
|
+
mat(0x220022, { emissive: 0xaa00ff, emissiveIntensity: 1.0, roughness: 0.1 })
|
|
36
|
+
);
|
|
37
|
+
marqueeLit.position.set(0, 1.64, 0.19);
|
|
38
|
+
g.add(marqueeLit);
|
|
39
|
+
|
|
40
|
+
// Marquee glow light
|
|
41
|
+
var marqueeLight = new THREE.PointLight(0xaa00ff, 0.5, 1.2);
|
|
42
|
+
marqueeLight.position.set(0, 1.72, 0.30);
|
|
43
|
+
g.add(marqueeLight);
|
|
44
|
+
|
|
45
|
+
// Angled monitor bezel
|
|
46
|
+
var bezel = new THREE.Mesh(
|
|
47
|
+
new THREE.BoxGeometry(0.54, 0.42, 0.025),
|
|
48
|
+
mat(0x080808, { roughness: 0.70 })
|
|
49
|
+
);
|
|
50
|
+
bezel.rotation.x = -0.30;
|
|
51
|
+
bezel.position.set(0, 1.22, 0.265);
|
|
52
|
+
g.add(bezel);
|
|
53
|
+
|
|
54
|
+
// Screen (emissive display)
|
|
55
|
+
var screen = new THREE.Mesh(
|
|
56
|
+
new THREE.BoxGeometry(0.46, 0.34, 0.010),
|
|
57
|
+
mat(0x000a22, { emissive: 0x0044ff, emissiveIntensity: 0.80, roughness: 0.1 })
|
|
58
|
+
);
|
|
59
|
+
screen.rotation.x = -0.30;
|
|
60
|
+
screen.position.set(0, 1.225, 0.273);
|
|
61
|
+
g.add(screen);
|
|
62
|
+
|
|
63
|
+
// Screen glow
|
|
64
|
+
var screenGlow = new THREE.PointLight(0x0044ff, 0.35, 0.9);
|
|
65
|
+
screenGlow.position.set(0, 1.22, 0.38);
|
|
66
|
+
g.add(screenGlow);
|
|
67
|
+
|
|
68
|
+
// Control panel (angled surface below screen)
|
|
69
|
+
var controlPanel = new THREE.Mesh(
|
|
70
|
+
new THREE.BoxGeometry(0.66, 0.06, 0.32),
|
|
71
|
+
mat(0x111318, { roughness: 0.45 })
|
|
72
|
+
);
|
|
73
|
+
controlPanel.rotation.x = -0.45;
|
|
74
|
+
controlPanel.position.set(0, 0.90, 0.24);
|
|
75
|
+
g.add(controlPanel);
|
|
76
|
+
|
|
77
|
+
// Joystick base
|
|
78
|
+
var joystickBase = new THREE.Mesh(
|
|
79
|
+
new THREE.CylinderGeometry(0.038, 0.038, 0.018, 10),
|
|
80
|
+
mat(0x222222, { roughness: 0.60 })
|
|
81
|
+
);
|
|
82
|
+
joystickBase.position.set(-0.14, 0.96, 0.25);
|
|
83
|
+
g.add(joystickBase);
|
|
84
|
+
|
|
85
|
+
// Joystick stick
|
|
86
|
+
var joystick = new THREE.Mesh(
|
|
87
|
+
new THREE.CylinderGeometry(0.012, 0.012, 0.065, 8),
|
|
88
|
+
mat(0x333333, { roughness: 0.50 })
|
|
89
|
+
);
|
|
90
|
+
joystick.position.set(-0.14, 1.01, 0.25);
|
|
91
|
+
g.add(joystick);
|
|
92
|
+
|
|
93
|
+
// Joystick ball top
|
|
94
|
+
var ball = new THREE.Mesh(
|
|
95
|
+
new THREE.SphereGeometry(0.022, 10, 8),
|
|
96
|
+
mat(0xcc0000, { roughness: 0.40 })
|
|
97
|
+
);
|
|
98
|
+
ball.position.set(-0.14, 1.04, 0.25);
|
|
99
|
+
g.add(ball);
|
|
100
|
+
|
|
101
|
+
// Action buttons (4 colored circles)
|
|
102
|
+
var btnColors = [0xee2211, 0x2288ee, 0x22cc44, 0xeecc00];
|
|
103
|
+
btnColors.forEach(function(color, i) {
|
|
104
|
+
var btn = new THREE.Mesh(
|
|
105
|
+
new THREE.CylinderGeometry(0.022, 0.022, 0.018, 10),
|
|
106
|
+
mat(color, { roughness: 0.45 })
|
|
107
|
+
);
|
|
108
|
+
var bx = 0.06 + (i % 2) * 0.055;
|
|
109
|
+
var bz = 0.22 + Math.floor(i / 2) * 0.055;
|
|
110
|
+
btn.position.set(bx, 0.962, bz);
|
|
111
|
+
g.add(btn);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Side panel decorative stripe (neon line)
|
|
115
|
+
var stripe = new THREE.Mesh(
|
|
116
|
+
new THREE.BoxGeometry(0.008, 1.10, 0.012),
|
|
117
|
+
mat(0xff00cc, { emissive: 0xff00cc, emissiveIntensity: 0.80 })
|
|
118
|
+
);
|
|
119
|
+
stripe.position.set(0.352, 0.80, 0);
|
|
120
|
+
g.add(stripe);
|
|
121
|
+
|
|
122
|
+
// Coin slot
|
|
123
|
+
var coinSlot = new THREE.Mesh(
|
|
124
|
+
new THREE.BoxGeometry(0.055, 0.010, 0.022),
|
|
125
|
+
mat(0x333333, { roughness: 0.60, metalness: 0.40 })
|
|
126
|
+
);
|
|
127
|
+
coinSlot.position.set(0, 0.70, 0.305);
|
|
128
|
+
g.add(coinSlot);
|
|
129
|
+
|
|
130
|
+
// Base kick panel
|
|
131
|
+
var kick = new THREE.Mesh(
|
|
132
|
+
new THREE.BoxGeometry(0.70, 0.20, 0.60),
|
|
133
|
+
mat(0x0a0c10, { roughness: 0.60 })
|
|
134
|
+
);
|
|
135
|
+
kick.position.y = 0.10;
|
|
136
|
+
kick.castShadow = true;
|
|
137
|
+
g.add(kick);
|
|
138
|
+
|
|
139
|
+
return g;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'archway',
|
|
6
|
+
name: 'Archway',
|
|
7
|
+
category: 'structural',
|
|
8
|
+
icon: 'Ar',
|
|
9
|
+
gridW: 2, gridD: 1, height: 3,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
var walnut = PAL.walnutDark();
|
|
14
|
+
var chrome = PAL.chrome();
|
|
15
|
+
|
|
16
|
+
// Left pillar
|
|
17
|
+
var pillarL = new THREE.Mesh(
|
|
18
|
+
new THREE.BoxGeometry(0.28, 3, 0.3),
|
|
19
|
+
walnut
|
|
20
|
+
);
|
|
21
|
+
pillarL.position.x = -0.86;
|
|
22
|
+
pillarL.castShadow = true;
|
|
23
|
+
g.add(pillarL);
|
|
24
|
+
|
|
25
|
+
// Right pillar
|
|
26
|
+
var pillarR = pillarL.clone();
|
|
27
|
+
pillarR.position.x = 0.86;
|
|
28
|
+
g.add(pillarR);
|
|
29
|
+
|
|
30
|
+
// Top lintel beam (horizontal span)
|
|
31
|
+
var lintel = new THREE.Mesh(
|
|
32
|
+
new THREE.BoxGeometry(2, 0.35, 0.3),
|
|
33
|
+
walnut
|
|
34
|
+
);
|
|
35
|
+
lintel.position.y = 1.325;
|
|
36
|
+
lintel.castShadow = true;
|
|
37
|
+
g.add(lintel);
|
|
38
|
+
|
|
39
|
+
// Chrome accent strip on lintel front face
|
|
40
|
+
var lintelStrip = new THREE.Mesh(
|
|
41
|
+
new THREE.BoxGeometry(2, 0.05, 0.01),
|
|
42
|
+
chrome
|
|
43
|
+
);
|
|
44
|
+
lintelStrip.position.set(0, 1.325, 0.155);
|
|
45
|
+
g.add(lintelStrip);
|
|
46
|
+
|
|
47
|
+
// Chrome base caps on pillars
|
|
48
|
+
var capGeo = new THREE.BoxGeometry(0.32, 0.07, 0.34);
|
|
49
|
+
var capL = new THREE.Mesh(capGeo, chrome);
|
|
50
|
+
capL.position.set(-0.86, -1.465, 0);
|
|
51
|
+
g.add(capL);
|
|
52
|
+
var capR = new THREE.Mesh(capGeo, chrome);
|
|
53
|
+
capR.position.set(0.86, -1.465, 0);
|
|
54
|
+
g.add(capR);
|
|
55
|
+
|
|
56
|
+
// Chrome crown caps on pillars (top)
|
|
57
|
+
var crownL = new THREE.Mesh(capGeo, chrome);
|
|
58
|
+
crownL.position.set(-0.86, 1.465, 0);
|
|
59
|
+
g.add(crownL);
|
|
60
|
+
var crownR = new THREE.Mesh(capGeo, chrome);
|
|
61
|
+
crownR.position.set(0.86, 1.465, 0);
|
|
62
|
+
g.add(crownR);
|
|
63
|
+
|
|
64
|
+
// Arch soffit — curved underside suggestion (thin curved strip)
|
|
65
|
+
var archCurve = new THREE.Mesh(
|
|
66
|
+
new THREE.TorusGeometry(0.72, 0.04, 6, 18, Math.PI),
|
|
67
|
+
chrome
|
|
68
|
+
);
|
|
69
|
+
archCurve.rotation.y = Math.PI / 2;
|
|
70
|
+
archCurve.rotation.z = Math.PI;
|
|
71
|
+
archCurve.position.y = 0.65;
|
|
72
|
+
archCurve.castShadow = true;
|
|
73
|
+
g.add(archCurve);
|
|
74
|
+
|
|
75
|
+
return g;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'bar_counter',
|
|
6
|
+
name: 'Bar Counter',
|
|
7
|
+
category: 'kitchen',
|
|
8
|
+
icon: 'Ba',
|
|
9
|
+
gridW: 3, gridD: 1, height: 1.1,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
// Walnut countertop
|
|
14
|
+
var top = new THREE.Mesh(
|
|
15
|
+
new THREE.BoxGeometry(3.0, 0.06, 1.2),
|
|
16
|
+
PAL.walnutDark()
|
|
17
|
+
);
|
|
18
|
+
top.position.y = 1.1;
|
|
19
|
+
top.castShadow = true;
|
|
20
|
+
top.receiveShadow = true;
|
|
21
|
+
g.add(top);
|
|
22
|
+
|
|
23
|
+
// Countertop front overhang edge strip (gold trim)
|
|
24
|
+
var edgeTrim = new THREE.Mesh(
|
|
25
|
+
new THREE.BoxGeometry(3.0, 0.025, 0.02),
|
|
26
|
+
PAL.gold()
|
|
27
|
+
);
|
|
28
|
+
edgeTrim.position.set(0, 1.075, 0.61);
|
|
29
|
+
g.add(edgeTrim);
|
|
30
|
+
|
|
31
|
+
// Main front panel (dark)
|
|
32
|
+
var frontPanel = new THREE.Mesh(
|
|
33
|
+
new THREE.BoxGeometry(3.0, 0.92, 0.06),
|
|
34
|
+
mat(0x111318, { roughness: 0.45, metalness: 0.10 })
|
|
35
|
+
);
|
|
36
|
+
frontPanel.position.set(0, 0.59, 0.57);
|
|
37
|
+
frontPanel.castShadow = true;
|
|
38
|
+
g.add(frontPanel);
|
|
39
|
+
|
|
40
|
+
// Cabinet body
|
|
41
|
+
var body = new THREE.Mesh(
|
|
42
|
+
new THREE.BoxGeometry(2.96, 0.90, 1.08),
|
|
43
|
+
mat(0x16181e, { roughness: 0.50 })
|
|
44
|
+
);
|
|
45
|
+
body.position.set(0, 0.59, 0);
|
|
46
|
+
body.castShadow = true;
|
|
47
|
+
g.add(body);
|
|
48
|
+
|
|
49
|
+
// LED underglow strip — neon blue emissive bar under front panel
|
|
50
|
+
var led = new THREE.Mesh(
|
|
51
|
+
new THREE.BoxGeometry(2.9, 0.015, 0.025),
|
|
52
|
+
mat(0x58a6ff, { emissive: 0x58a6ff, emissiveIntensity: 1.2, roughness: 0.3 })
|
|
53
|
+
);
|
|
54
|
+
led.position.set(0, 0.085, 0.575);
|
|
55
|
+
g.add(led);
|
|
56
|
+
|
|
57
|
+
// PointLight for LED underglow
|
|
58
|
+
var glow = new THREE.PointLight(0x58a6ff, 0.6, 1.8);
|
|
59
|
+
glow.position.set(0, 0.06, 0.5);
|
|
60
|
+
g.add(glow);
|
|
61
|
+
|
|
62
|
+
// Base plinth (dark metal strip at floor)
|
|
63
|
+
var plinth = new THREE.Mesh(
|
|
64
|
+
new THREE.BoxGeometry(3.0, 0.08, 1.2),
|
|
65
|
+
PAL.darkMetal()
|
|
66
|
+
);
|
|
67
|
+
plinth.position.y = 0.04;
|
|
68
|
+
plinth.castShadow = true;
|
|
69
|
+
g.add(plinth);
|
|
70
|
+
|
|
71
|
+
// Vertical divider panels inside (3 sections)
|
|
72
|
+
var dividerMat = mat(0x1e2128, { roughness: 0.55 });
|
|
73
|
+
var dividerGeo = new THREE.BoxGeometry(0.04, 0.86, 1.04);
|
|
74
|
+
[-1.0, 0, 1.0].forEach(function(x) {
|
|
75
|
+
var d = new THREE.Mesh(dividerGeo, dividerMat);
|
|
76
|
+
d.position.set(x, 0.59, 0);
|
|
77
|
+
g.add(d);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Chrome rail along bar top front edge
|
|
81
|
+
var rail = new THREE.Mesh(
|
|
82
|
+
new THREE.CylinderGeometry(0.018, 0.018, 3.0, 10),
|
|
83
|
+
PAL.chrome()
|
|
84
|
+
);
|
|
85
|
+
rail.rotation.z = Math.PI / 2;
|
|
86
|
+
rail.position.set(0, 1.14, 0.58);
|
|
87
|
+
g.add(rail);
|
|
88
|
+
|
|
89
|
+
return g;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'bar_stool',
|
|
6
|
+
name: 'Bar Stool',
|
|
7
|
+
category: 'kitchen',
|
|
8
|
+
icon: 'BS',
|
|
9
|
+
gridW: 1, gridD: 1, height: 0.75,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
// Round seat (dark leather pad)
|
|
14
|
+
var seat = new THREE.Mesh(
|
|
15
|
+
new THREE.CylinderGeometry(0.18, 0.17, 0.06, 20),
|
|
16
|
+
PAL.leatherBlack()
|
|
17
|
+
);
|
|
18
|
+
seat.position.y = 0.75;
|
|
19
|
+
seat.castShadow = true;
|
|
20
|
+
seat.receiveShadow = true;
|
|
21
|
+
g.add(seat);
|
|
22
|
+
|
|
23
|
+
// Seat chrome rim
|
|
24
|
+
var seatRim = new THREE.Mesh(
|
|
25
|
+
new THREE.TorusGeometry(0.18, 0.012, 8, 24),
|
|
26
|
+
PAL.chrome()
|
|
27
|
+
);
|
|
28
|
+
seatRim.rotation.x = Math.PI / 2;
|
|
29
|
+
seatRim.position.y = 0.722;
|
|
30
|
+
g.add(seatRim);
|
|
31
|
+
|
|
32
|
+
// Main chrome post
|
|
33
|
+
var post = new THREE.Mesh(
|
|
34
|
+
new THREE.CylinderGeometry(0.025, 0.025, 0.60, 12),
|
|
35
|
+
PAL.chrome()
|
|
36
|
+
);
|
|
37
|
+
post.position.y = 0.42;
|
|
38
|
+
post.castShadow = true;
|
|
39
|
+
g.add(post);
|
|
40
|
+
|
|
41
|
+
// Pneumatic sleeve (mid-post, slightly wider)
|
|
42
|
+
var sleeve = new THREE.Mesh(
|
|
43
|
+
new THREE.CylinderGeometry(0.036, 0.036, 0.18, 12),
|
|
44
|
+
PAL.chromeBrushed()
|
|
45
|
+
);
|
|
46
|
+
sleeve.position.y = 0.54;
|
|
47
|
+
g.add(sleeve);
|
|
48
|
+
|
|
49
|
+
// Circular base (flat disc)
|
|
50
|
+
var base = new THREE.Mesh(
|
|
51
|
+
new THREE.CylinderGeometry(0.28, 0.30, 0.04, 24),
|
|
52
|
+
PAL.chromeBrushed()
|
|
53
|
+
);
|
|
54
|
+
base.position.y = 0.02;
|
|
55
|
+
base.castShadow = true;
|
|
56
|
+
base.receiveShadow = true;
|
|
57
|
+
g.add(base);
|
|
58
|
+
|
|
59
|
+
// 4 floor glide feet around base rim
|
|
60
|
+
var glideMat = mat(0x111111, { roughness: 0.9 });
|
|
61
|
+
var glideGeo = new THREE.CylinderGeometry(0.022, 0.022, 0.018, 8);
|
|
62
|
+
[0, 1, 2, 3].forEach(function(i) {
|
|
63
|
+
var angle = (i / 4) * Math.PI * 2;
|
|
64
|
+
var glide = new THREE.Mesh(glideGeo, glideMat);
|
|
65
|
+
glide.position.set(Math.cos(angle) * 0.26, 0.009, Math.sin(angle) * 0.26);
|
|
66
|
+
g.add(glide);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return g;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'beanbag',
|
|
6
|
+
name: 'Beanbag Chair',
|
|
7
|
+
category: 'recreation',
|
|
8
|
+
icon: 'BB',
|
|
9
|
+
gridW: 1, gridD: 1, height: 0.4,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
// Pick a random color from 4 options
|
|
14
|
+
var colorOptions = [0x2a1f5e, 0x5e1f2a, 0x1f4a2a, 0x4a3a1f];
|
|
15
|
+
var color = colorOptions[Math.floor(Math.random() * colorOptions.length)];
|
|
16
|
+
var trimColors = [0x4433aa, 0xaa3344, 0x338855, 0x887744];
|
|
17
|
+
var trimIdx = colorOptions.indexOf(color);
|
|
18
|
+
var trimColor = trimColors[trimIdx >= 0 ? trimIdx : 0];
|
|
19
|
+
|
|
20
|
+
// Main squashed sphere body
|
|
21
|
+
var body = new THREE.Mesh(
|
|
22
|
+
new THREE.SphereGeometry(0.40, 22, 16),
|
|
23
|
+
mat(color, { roughness: 0.88 })
|
|
24
|
+
);
|
|
25
|
+
body.scale.set(1.0, 0.55, 1.0);
|
|
26
|
+
body.position.y = 0.22;
|
|
27
|
+
body.castShadow = true;
|
|
28
|
+
body.receiveShadow = true;
|
|
29
|
+
g.add(body);
|
|
30
|
+
|
|
31
|
+
// Slightly lighter top section (highlight)
|
|
32
|
+
var top = new THREE.Mesh(
|
|
33
|
+
new THREE.SphereGeometry(0.26, 16, 12),
|
|
34
|
+
mat(trimColor, { roughness: 0.85 })
|
|
35
|
+
);
|
|
36
|
+
top.scale.set(1.0, 0.45, 1.0);
|
|
37
|
+
top.position.y = 0.32;
|
|
38
|
+
g.add(top);
|
|
39
|
+
|
|
40
|
+
// Seam lines (thin dark strips around middle)
|
|
41
|
+
var seamMat = mat(0x111111, { roughness: 0.90 });
|
|
42
|
+
var seamGeo = new THREE.TorusGeometry(0.38, 0.012, 6, 28);
|
|
43
|
+
var seamH = new THREE.Mesh(seamGeo, seamMat);
|
|
44
|
+
seamH.position.y = 0.20;
|
|
45
|
+
g.add(seamH);
|
|
46
|
+
|
|
47
|
+
// Cross seam (vertical ring)
|
|
48
|
+
var seamV = new THREE.Mesh(seamGeo, seamMat);
|
|
49
|
+
seamV.rotation.y = Math.PI / 2;
|
|
50
|
+
seamV.scale.set(0.7, 0.5, 0.7);
|
|
51
|
+
seamV.position.y = 0.22;
|
|
52
|
+
g.add(seamV);
|
|
53
|
+
|
|
54
|
+
// Small logo tag (tiny contrast strip on front)
|
|
55
|
+
var tag = new THREE.Mesh(
|
|
56
|
+
new THREE.BoxGeometry(0.055, 0.025, 0.008),
|
|
57
|
+
mat(0xffffff, { roughness: 0.80 })
|
|
58
|
+
);
|
|
59
|
+
tag.position.set(0, 0.22, 0.40);
|
|
60
|
+
g.add(tag);
|
|
61
|
+
|
|
62
|
+
return g;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'bench',
|
|
6
|
+
name: 'Park Bench',
|
|
7
|
+
category: 'exterior',
|
|
8
|
+
icon: 'Bn',
|
|
9
|
+
gridW: 2, gridD: 1, height: 0.8,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
var walnut = PAL.walnutLight();
|
|
14
|
+
var chrome = PAL.chrome();
|
|
15
|
+
|
|
16
|
+
// 3 seat slats
|
|
17
|
+
var slatGeo = new THREE.BoxGeometry(1.50, 0.038, 0.10);
|
|
18
|
+
[-0.14, 0, 0.14].forEach(function(z) {
|
|
19
|
+
var slat = new THREE.Mesh(slatGeo, walnut);
|
|
20
|
+
slat.position.set(0, 0.48, z);
|
|
21
|
+
slat.castShadow = true;
|
|
22
|
+
slat.receiveShadow = true;
|
|
23
|
+
g.add(slat);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// 3 back slats (angled slightly)
|
|
27
|
+
var backSlatGeo = new THREE.BoxGeometry(1.50, 0.038, 0.10);
|
|
28
|
+
[0, 0.12, 0.24].forEach(function(i, idx) {
|
|
29
|
+
var slat = new THREE.Mesh(backSlatGeo, walnut);
|
|
30
|
+
slat.rotation.x = -0.18;
|
|
31
|
+
slat.position.set(0, 0.57 + idx * 0.12, -0.24 + idx * 0.03);
|
|
32
|
+
slat.castShadow = true;
|
|
33
|
+
g.add(slat);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Left chrome leg frame (L-shape: vertical + diagonal brace)
|
|
37
|
+
var legGeo = new THREE.BoxGeometry(0.025, 0.48, 0.025);
|
|
38
|
+
var leftLegF = new THREE.Mesh(legGeo, chrome);
|
|
39
|
+
leftLegF.position.set(-0.64, 0.24, 0.16);
|
|
40
|
+
leftLegF.castShadow = true;
|
|
41
|
+
g.add(leftLegF);
|
|
42
|
+
|
|
43
|
+
var leftLegB = new THREE.Mesh(legGeo, chrome);
|
|
44
|
+
leftLegB.position.set(-0.64, 0.24, -0.16);
|
|
45
|
+
leftLegB.castShadow = true;
|
|
46
|
+
g.add(leftLegB);
|
|
47
|
+
|
|
48
|
+
// Right legs
|
|
49
|
+
var rightLegF = leftLegF.clone();
|
|
50
|
+
rightLegF.position.x = 0.64;
|
|
51
|
+
g.add(rightLegF);
|
|
52
|
+
|
|
53
|
+
var rightLegB = leftLegB.clone();
|
|
54
|
+
rightLegB.position.x = 0.64;
|
|
55
|
+
g.add(rightLegB);
|
|
56
|
+
|
|
57
|
+
// Horizontal chrome stretcher bars
|
|
58
|
+
var stretcherGeo = new THREE.BoxGeometry(1.50, 0.020, 0.020);
|
|
59
|
+
var frontStr = new THREE.Mesh(stretcherGeo, chrome);
|
|
60
|
+
frontStr.position.set(0, 0.22, 0.16);
|
|
61
|
+
g.add(frontStr);
|
|
62
|
+
|
|
63
|
+
var backStr = new THREE.Mesh(stretcherGeo, chrome);
|
|
64
|
+
backStr.position.set(0, 0.22, -0.16);
|
|
65
|
+
g.add(backStr);
|
|
66
|
+
|
|
67
|
+
// Back support verticals (angled)
|
|
68
|
+
var backVertGeo = new THREE.BoxGeometry(0.025, 0.44, 0.025);
|
|
69
|
+
var leftBV = new THREE.Mesh(backVertGeo, chrome);
|
|
70
|
+
leftBV.rotation.x = -0.18;
|
|
71
|
+
leftBV.position.set(-0.64, 0.68, -0.22);
|
|
72
|
+
leftBV.castShadow = true;
|
|
73
|
+
g.add(leftBV);
|
|
74
|
+
|
|
75
|
+
var rightBV = leftBV.clone();
|
|
76
|
+
rightBV.position.x = 0.64;
|
|
77
|
+
g.add(rightBV);
|
|
78
|
+
|
|
79
|
+
// Chrome armrests
|
|
80
|
+
var armGeo = new THREE.BoxGeometry(0.025, 0.025, 0.38);
|
|
81
|
+
var leftArm = new THREE.Mesh(armGeo, chrome);
|
|
82
|
+
leftArm.position.set(-0.64, 0.52, -0.01);
|
|
83
|
+
g.add(leftArm);
|
|
84
|
+
var rightArm = leftArm.clone();
|
|
85
|
+
rightArm.position.x = 0.64;
|
|
86
|
+
g.add(rightArm);
|
|
87
|
+
|
|
88
|
+
// Rubber floor pads
|
|
89
|
+
var padMat = mat(0x0a0a0a, { roughness: 0.92 });
|
|
90
|
+
var padGeo = new THREE.CylinderGeometry(0.020, 0.020, 0.012, 8);
|
|
91
|
+
[[-0.64, 0.006, 0.16], [0.64, 0.006, 0.16], [-0.64, 0.006, -0.16], [0.64, 0.006, -0.16]].forEach(function(p) {
|
|
92
|
+
var pad = new THREE.Mesh(padGeo, padMat);
|
|
93
|
+
pad.position.set(p[0], p[1], p[2]);
|
|
94
|
+
g.add(pad);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return g;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { mat, PAL } from './materials.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
id: 'bollard',
|
|
6
|
+
name: 'Bollard',
|
|
7
|
+
category: 'exterior',
|
|
8
|
+
icon: 'Bo',
|
|
9
|
+
gridW: 1, gridD: 1, height: 0.8,
|
|
10
|
+
factory: function() {
|
|
11
|
+
var g = new THREE.Group();
|
|
12
|
+
|
|
13
|
+
// Main concrete cylindrical body (slightly tapered at bottom)
|
|
14
|
+
var body = new THREE.Mesh(
|
|
15
|
+
new THREE.CylinderGeometry(0.095, 0.110, 0.72, 16),
|
|
16
|
+
PAL.concrete()
|
|
17
|
+
);
|
|
18
|
+
body.position.y = 0.38;
|
|
19
|
+
body.castShadow = true;
|
|
20
|
+
body.receiveShadow = true;
|
|
21
|
+
g.add(body);
|
|
22
|
+
|
|
23
|
+
// Domed cap (rounded top)
|
|
24
|
+
var cap = new THREE.Mesh(
|
|
25
|
+
new THREE.SphereGeometry(0.098, 14, 10, 0, Math.PI * 2, 0, Math.PI * 0.5),
|
|
26
|
+
mat(0x222530, { roughness: 0.75 })
|
|
27
|
+
);
|
|
28
|
+
cap.position.y = 0.740;
|
|
29
|
+
cap.castShadow = true;
|
|
30
|
+
g.add(cap);
|
|
31
|
+
|
|
32
|
+
// Reflective yellow safety band (wide stripe near top)
|
|
33
|
+
var yellowBand = new THREE.Mesh(
|
|
34
|
+
new THREE.CylinderGeometry(0.097, 0.097, 0.065, 16),
|
|
35
|
+
mat(0xffcc00, { roughness: 0.35, metalness: 0.10, emissive: 0xffcc00, emissiveIntensity: 0.15 })
|
|
36
|
+
);
|
|
37
|
+
yellowBand.position.y = 0.62;
|
|
38
|
+
g.add(yellowBand);
|
|
39
|
+
|
|
40
|
+
// Narrow black divider bands above and below yellow
|
|
41
|
+
var divMat = mat(0x0a0a0a, { roughness: 0.75 });
|
|
42
|
+
var divGeo = new THREE.CylinderGeometry(0.098, 0.098, 0.014, 16);
|
|
43
|
+
[0.587, 0.657].forEach(function(y) {
|
|
44
|
+
var div = new THREE.Mesh(divGeo, divMat);
|
|
45
|
+
div.position.y = y;
|
|
46
|
+
g.add(div);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Secondary narrow grey band mid-body
|
|
50
|
+
var greyBand = new THREE.Mesh(
|
|
51
|
+
new THREE.CylinderGeometry(0.1015, 0.1015, 0.022, 16),
|
|
52
|
+
mat(0x3a3d45, { roughness: 0.55 })
|
|
53
|
+
);
|
|
54
|
+
greyBand.position.y = 0.30;
|
|
55
|
+
g.add(greyBand);
|
|
56
|
+
|
|
57
|
+
// Embedded anchor ring at base (chrome)
|
|
58
|
+
var anchor = new THREE.Mesh(
|
|
59
|
+
new THREE.TorusGeometry(0.055, 0.010, 6, 14),
|
|
60
|
+
PAL.chromeBrushed()
|
|
61
|
+
);
|
|
62
|
+
anchor.rotation.x = Math.PI / 2;
|
|
63
|
+
anchor.position.y = 0.055;
|
|
64
|
+
g.add(anchor);
|
|
65
|
+
|
|
66
|
+
// Ground base plate (flush with floor, dark concrete)
|
|
67
|
+
var plate = new THREE.Mesh(
|
|
68
|
+
new THREE.CylinderGeometry(0.130, 0.130, 0.028, 16),
|
|
69
|
+
mat(0x1a1d24, { roughness: 0.90 })
|
|
70
|
+
);
|
|
71
|
+
plate.position.y = 0.014;
|
|
72
|
+
plate.receiveShadow = true;
|
|
73
|
+
g.add(plate);
|
|
74
|
+
|
|
75
|
+
// 4 small anchor bolts around base plate
|
|
76
|
+
var boltMat = PAL.chromeBrushed();
|
|
77
|
+
var boltGeo = new THREE.CylinderGeometry(0.008, 0.008, 0.030, 6);
|
|
78
|
+
[0, 1, 2, 3].forEach(function(i) {
|
|
79
|
+
var angle = (i / 4) * Math.PI * 2 + Math.PI / 4;
|
|
80
|
+
var bolt = new THREE.Mesh(boltGeo, boltMat);
|
|
81
|
+
bolt.position.set(Math.cos(angle) * 0.108, 0.015, Math.sin(angle) * 0.108);
|
|
82
|
+
g.add(bolt);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return g;
|
|
86
|
+
}
|
|
87
|
+
};
|