opencroc 1.8.2 → 1.8.3

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.
Files changed (44) hide show
  1. package/package.json +1 -1
  2. package/dist/web/index.html +0 -12
  3. package/dist/web/public/botreview/char_0.png +0 -0
  4. package/dist/web/public/botreview/char_1.png +0 -0
  5. package/dist/web/public/botreview/char_2.png +0 -0
  6. package/dist/web/public/botreview/coffee-machine.gif +0 -0
  7. package/dist/web/public/botreview/server.gif +0 -0
  8. package/dist/web/public/botreview/walls.png +0 -0
  9. package/dist/web/public/star/desk-v3.webp +0 -0
  10. package/dist/web/public/star/office_bg_small.webp +0 -0
  11. package/dist/web/public/star/star-idle-v5.png +0 -0
  12. package/dist/web/public/star/star-working-spritesheet-grid.webp +0 -0
  13. package/dist/web/src/app/AppLayout.tsx +0 -34
  14. package/dist/web/src/app/AppRouter.tsx +0 -46
  15. package/dist/web/src/app/bootstrap.tsx +0 -22
  16. package/dist/web/src/app/routes.tsx +0 -52
  17. package/dist/web/src/features/office/runtime/index.ts +0 -1
  18. package/dist/web/src/features/office/runtime/mount.ts +0 -809
  19. package/dist/web/src/features/pixel/runtime/index.ts +0 -1
  20. package/dist/web/src/features/pixel/runtime/mount.ts +0 -728
  21. package/dist/web/src/features/studio/runtime/index.ts +0 -1
  22. package/dist/web/src/features/studio/runtime/mount.ts +0 -664
  23. package/dist/web/src/features/three/engine/index.ts +0 -1
  24. package/dist/web/src/main.tsx +0 -7
  25. package/dist/web/src/pages/office/index.ts +0 -1
  26. package/dist/web/src/pages/office/page.tsx +0 -283
  27. package/dist/web/src/pages/pixel/index.ts +0 -1
  28. package/dist/web/src/pages/pixel/page.tsx +0 -564
  29. package/dist/web/src/pages/studio/index.ts +0 -1
  30. package/dist/web/src/pages/studio/page.tsx +0 -446
  31. package/dist/web/src/runtime/agents.ts +0 -738
  32. package/dist/web/src/runtime/camera.ts +0 -132
  33. package/dist/web/src/runtime/dataviz.ts +0 -312
  34. package/dist/web/src/runtime/effects.ts +0 -482
  35. package/dist/web/src/runtime/engine.ts +0 -528
  36. package/dist/web/src/runtime/office.ts +0 -932
  37. package/dist/web/src/runtime/state.ts +0 -37
  38. package/dist/web/src/runtime/ui.ts +0 -388
  39. package/dist/web/src/shared/assets.ts +0 -4
  40. package/dist/web/src/shared/navigation.ts +0 -47
  41. package/dist/web/src/styles/app-layout.css +0 -19
  42. package/dist/web/src/styles/office.css +0 -268
  43. package/dist/web/tsconfig.json +0 -28
  44. package/dist/web/vite.config.ts +0 -93
@@ -1,482 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════════════════════════
2
- OpenCroc Studio 3D — Particle Systems & Effects
3
- ~2000 lines
4
- ═══════════════════════════════════════════════════════════════════════════════ */
5
-
6
- import * as THREE from 'three';
7
-
8
- function disposeObject3D(object) {
9
- object?.traverse?.((child) => {
10
- child.geometry?.dispose?.();
11
- if (Array.isArray(child.material)) {
12
- child.material.forEach((material) => material?.dispose?.());
13
- } else {
14
- child.material?.dispose?.();
15
- }
16
- });
17
- }
18
-
19
- /* ═══════════════════════════════════════════════════════════════════════════════
20
- ParticleManager
21
- ═══════════════════════════════════════════════════════════════════════════════ */
22
- export class ParticleManager {
23
- constructor(scene) {
24
- this.scene = scene;
25
- this.systems = [];
26
- this._time = 0;
27
-
28
- this._createAmbientParticles();
29
- this._createDataStreamParticles();
30
- this._createGroundGlow();
31
- }
32
-
33
- /* ─── Update each frame ──────────────────────────────────────────────── */
34
- update(dt) {
35
- this._time += dt;
36
-
37
- for (const sys of this.systems) {
38
- if (sys.update) sys.update(dt, this._time);
39
- }
40
- }
41
-
42
- /* ═════════════════════════════════════════════════════════════════════════
43
- Ambient Floating Particles — Dust motes & bokeh
44
- ═════════════════════════════════════════════════════════════════════════ */
45
- _createAmbientParticles() {
46
- const count = 500;
47
- const positions = new Float32Array(count * 3);
48
- const velocities = new Float32Array(count * 3);
49
- const sizes = new Float32Array(count);
50
- const opacities = new Float32Array(count);
51
- const colors = new Float32Array(count * 3);
52
-
53
- const palette = [
54
- new THREE.Color(0x34d399),
55
- new THREE.Color(0x60a5fa),
56
- new THREE.Color(0xa78bfa),
57
- new THREE.Color(0x22d3ee),
58
- new THREE.Color(0xffffff),
59
- ];
60
-
61
- for (let i = 0; i < count; i++) {
62
- positions[i * 3] = (Math.random() - 0.5) * 40;
63
- positions[i * 3 + 1] = Math.random() * 15;
64
- positions[i * 3 + 2] = (Math.random() - 0.5) * 30;
65
-
66
- velocities[i * 3] = (Math.random() - 0.5) * 0.2;
67
- velocities[i * 3 + 1] = 0.05 + Math.random() * 0.15;
68
- velocities[i * 3 + 2] = (Math.random() - 0.5) * 0.2;
69
-
70
- sizes[i] = 0.02 + Math.random() * 0.08;
71
- opacities[i] = 0.1 + Math.random() * 0.4;
72
-
73
- const c = palette[Math.floor(Math.random() * palette.length)];
74
- colors[i * 3] = c.r;
75
- colors[i * 3 + 1] = c.g;
76
- colors[i * 3 + 2] = c.b;
77
- }
78
-
79
- const geo = new THREE.BufferGeometry();
80
- geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
81
- geo.setAttribute('aVelocity', new THREE.BufferAttribute(velocities, 3));
82
- geo.setAttribute('aSize', new THREE.BufferAttribute(sizes, 1));
83
- geo.setAttribute('aOpacity', new THREE.BufferAttribute(opacities, 1));
84
- geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));
85
-
86
- const mat = new THREE.ShaderMaterial({
87
- uniforms: {
88
- uTime: { value: 0 },
89
- uPixelRatio: { value: Math.min(window.devicePixelRatio, 2) },
90
- },
91
- vertexShader: `
92
- attribute float aSize;
93
- attribute float aOpacity;
94
- attribute vec3 aVelocity;
95
- attribute vec3 color;
96
- uniform float uTime;
97
- uniform float uPixelRatio;
98
- varying float vOpacity;
99
- varying vec3 vColor;
100
- void main() {
101
- vOpacity = aOpacity;
102
- vColor = color;
103
- vec3 pos = position;
104
- // Gentle floating motion
105
- pos.x += sin(uTime * aVelocity.x + position.z * 2.0) * 0.5;
106
- pos.y += mod(pos.y + uTime * aVelocity.y, 15.0);
107
- pos.z += cos(uTime * aVelocity.z + position.x * 2.0) * 0.5;
108
- vec4 mvPos = modelViewMatrix * vec4(pos, 1.0);
109
- gl_PointSize = aSize * uPixelRatio * (150.0 / -mvPos.z);
110
- gl_Position = projectionMatrix * mvPos;
111
- }
112
- `,
113
- fragmentShader: `
114
- varying float vOpacity;
115
- varying vec3 vColor;
116
- void main() {
117
- float d = length(gl_PointCoord - vec2(0.5));
118
- if (d > 0.5) discard;
119
- float alpha = (1.0 - smoothstep(0.2, 0.5, d)) * vOpacity;
120
- gl_FragColor = vec4(vColor, alpha);
121
- }
122
- `,
123
- transparent: true,
124
- depthWrite: false,
125
- blending: THREE.AdditiveBlending,
126
- vertexColors: true,
127
- });
128
-
129
- const points = new THREE.Points(geo, mat);
130
- points.name = 'ambient-particles';
131
- this.scene.add(points);
132
-
133
- this.systems.push({
134
- mesh: points,
135
- update: (dt, time) => {
136
- mat.uniforms.uTime.value = time;
137
- },
138
- });
139
- }
140
-
141
- /* ═════════════════════════════════════════════════════════════════════════
142
- Data Stream Particles — Vertical data flow columns
143
- ═════════════════════════════════════════════════════════════════════════ */
144
- _createDataStreamParticles() {
145
- const streamPositions = [
146
- { x: -10, z: -4.5 }, // Server area
147
- { x: 0, z: 0 }, // Center hologram
148
- { x: -10, z: -1.5 }, // Server area 2
149
- ];
150
-
151
- streamPositions.forEach((sp, idx) => {
152
- const count = 80;
153
- const positions = new Float32Array(count * 3);
154
- const speeds = new Float32Array(count);
155
-
156
- for (let i = 0; i < count; i++) {
157
- positions[i * 3] = sp.x + (Math.random() - 0.5) * 0.6;
158
- positions[i * 3 + 1] = Math.random() * 6;
159
- positions[i * 3 + 2] = sp.z + (Math.random() - 0.5) * 0.6;
160
- speeds[i] = 1.0 + Math.random() * 2.0;
161
- }
162
-
163
- const geo = new THREE.BufferGeometry();
164
- geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
165
- geo.setAttribute('aSpeed', new THREE.BufferAttribute(speeds, 1));
166
-
167
- const color = idx === 1 ? 0x34d399 : (idx === 0 ? 0x60a5fa : 0xa78bfa);
168
-
169
- const mat = new THREE.ShaderMaterial({
170
- uniforms: {
171
- uTime: { value: 0 },
172
- uColor: { value: new THREE.Color(color) },
173
- uPixelRatio: { value: Math.min(window.devicePixelRatio, 2) },
174
- },
175
- vertexShader: `
176
- attribute float aSpeed;
177
- uniform float uTime;
178
- uniform float uPixelRatio;
179
- varying float vAlpha;
180
- void main() {
181
- vec3 pos = position;
182
- float y = mod(pos.y + uTime * aSpeed, 6.0);
183
- pos.y = y + 0.3;
184
- vAlpha = 1.0 - y / 6.0; // Fade as they rise
185
- vec4 mvPos = modelViewMatrix * vec4(pos, 1.0);
186
- gl_PointSize = 3.0 * uPixelRatio * (100.0 / -mvPos.z);
187
- gl_Position = projectionMatrix * mvPos;
188
- }
189
- `,
190
- fragmentShader: `
191
- uniform vec3 uColor;
192
- varying float vAlpha;
193
- void main() {
194
- float d = length(gl_PointCoord - vec2(0.5));
195
- if (d > 0.5) discard;
196
- float alpha = (1.0 - d * 2.0) * vAlpha * 0.6;
197
- gl_FragColor = vec4(uColor, alpha);
198
- }
199
- `,
200
- transparent: true,
201
- depthWrite: false,
202
- blending: THREE.AdditiveBlending,
203
- });
204
-
205
- const points = new THREE.Points(geo, mat);
206
- points.name = `data-stream-${idx}`;
207
- this.scene.add(points);
208
-
209
- this.systems.push({
210
- mesh: points,
211
- update: (dt, time) => {
212
- mat.uniforms.uTime.value = time;
213
- },
214
- });
215
- });
216
- }
217
-
218
- /* ═════════════════════════════════════════════════════════════════════════
219
- Ground Glow — Circle of light on the ground near center
220
- ═════════════════════════════════════════════════════════════════════════ */
221
- _createGroundGlow() {
222
- const glowGeo = new THREE.CircleGeometry(3, 32);
223
- const glowMat = new THREE.ShaderMaterial({
224
- uniforms: {
225
- uTime: { value: 0 },
226
- uColor: { value: new THREE.Color(0x34d399) },
227
- uIntensity: { value: 0.15 },
228
- },
229
- vertexShader: `
230
- varying vec2 vUv;
231
- void main() {
232
- vUv = uv;
233
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
234
- }
235
- `,
236
- fragmentShader: `
237
- uniform float uTime;
238
- uniform vec3 uColor;
239
- uniform float uIntensity;
240
- varying vec2 vUv;
241
- void main() {
242
- vec2 center = vUv - vec2(0.5);
243
- float dist = length(center) * 2.0;
244
- float ring1 = smoothstep(0.8, 0.85, dist) - smoothstep(0.85, 0.9, dist);
245
- float ring2 = smoothstep(0.5, 0.55, dist) - smoothstep(0.55, 0.6, dist);
246
- float pulse = 0.5 + 0.5 * sin(uTime * 2.0);
247
- float glow = (1.0 - dist) * uIntensity;
248
- float rings = (ring1 + ring2 * 0.5) * 0.3 * pulse;
249
- float alpha = max(glow, rings);
250
- if (alpha < 0.01) discard;
251
- gl_FragColor = vec4(uColor, alpha);
252
- }
253
- `,
254
- transparent: true,
255
- depthWrite: false,
256
- side: THREE.DoubleSide,
257
- });
258
-
259
- const glow = new THREE.Mesh(glowGeo, glowMat);
260
- glow.rotation.x = -Math.PI / 2;
261
- glow.position.set(0, 0.22, 0);
262
- glow.name = 'ground-glow';
263
- this.scene.add(glow);
264
-
265
- this.systems.push({
266
- mesh: glow,
267
- update: (dt, time) => {
268
- glowMat.uniforms.uTime.value = time;
269
- },
270
- });
271
- }
272
-
273
- /* ═════════════════════════════════════════════════════════════════════════
274
- Celebration Explosion — Triggered on pipeline completion
275
- ═════════════════════════════════════════════════════════════════════════ */
276
- triggerCelebration() {
277
- const count = 200;
278
- const positions = new Float32Array(count * 3);
279
- const velocities = [];
280
- const colors = new Float32Array(count * 3);
281
- const sizes = new Float32Array(count);
282
-
283
- const palette = [
284
- new THREE.Color(0x34d399), new THREE.Color(0x60a5fa),
285
- new THREE.Color(0xfbbf24), new THREE.Color(0xf472b6),
286
- new THREE.Color(0xa78bfa), new THREE.Color(0x22d3ee),
287
- ];
288
-
289
- for (let i = 0; i < count; i++) {
290
- positions[i * 3] = 0;
291
- positions[i * 3 + 1] = 2;
292
- positions[i * 3 + 2] = 0;
293
-
294
- const theta = Math.random() * Math.PI * 2;
295
- const phi = Math.random() * Math.PI;
296
- const speed = 3 + Math.random() * 5;
297
- velocities.push(
298
- Math.sin(phi) * Math.cos(theta) * speed,
299
- Math.cos(phi) * speed * 0.5 + 4,
300
- Math.sin(phi) * Math.sin(theta) * speed,
301
- );
302
-
303
- const c = palette[Math.floor(Math.random() * palette.length)];
304
- colors[i * 3] = c.r;
305
- colors[i * 3 + 1] = c.g;
306
- colors[i * 3 + 2] = c.b;
307
-
308
- sizes[i] = 0.05 + Math.random() * 0.1;
309
- }
310
-
311
- const geo = new THREE.BufferGeometry();
312
- geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
313
- geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));
314
-
315
- const mat = new THREE.PointsMaterial({
316
- size: 0.08,
317
- transparent: true,
318
- opacity: 1.0,
319
- vertexColors: true,
320
- blending: THREE.AdditiveBlending,
321
- depthWrite: false,
322
- });
323
-
324
- const particles = new THREE.Points(geo, mat);
325
- particles.name = 'celebration';
326
- this.scene.add(particles);
327
-
328
- let life = 0;
329
- const sys = {
330
- mesh: particles,
331
- update: (dt) => {
332
- life += dt;
333
- if (life > 3) {
334
- this.scene.remove(particles);
335
- geo.dispose();
336
- mat.dispose();
337
- const idx = this.systems.indexOf(sys);
338
- if (idx >= 0) this.systems.splice(idx, 1);
339
- return;
340
- }
341
-
342
- const posArr = geo.attributes.position.array;
343
- for (let i = 0; i < count; i++) {
344
- posArr[i * 3] += velocities[i * 3] * dt;
345
- posArr[i * 3 + 1] += velocities[i * 3 + 1] * dt;
346
- posArr[i * 3 + 2] += velocities[i * 3 + 2] * dt;
347
- velocities[i * 3 + 1] -= 9.8 * dt; // Gravity
348
- }
349
- geo.attributes.position.needsUpdate = true;
350
- mat.opacity = Math.max(0, 1 - life / 3);
351
- },
352
- };
353
-
354
- this.systems.push(sys);
355
- }
356
-
357
- triggerAgentTransfer(from, to, kind = 'assigned') {
358
- if (!from || !to) return;
359
-
360
- const startColor = kind === 'released' ? 0xfbbf24 : 0x60a5fa;
361
- const endColor = kind === 'released' ? 0x34d399 : 0x22d3ee;
362
-
363
- this._triggerPulse(from.x, 0.34, from.z, startColor, kind === 'released' ? 0.8 : 1.1);
364
- this._triggerPulse(to.x, 0.34, to.z, endColor, kind === 'released' ? 1.2 : 0.9, 180);
365
-
366
- // Expanding ripple at the pond side (departure or arrival).
367
- const pondSide = kind === 'assigned' ? from : to;
368
- if (pondSide.x != null) this.triggerPondRipple(pondSide.x, pondSide.z ?? 6.2);
369
- }
370
-
371
- triggerPondRipple(x, z) {
372
- const geo = new THREE.RingGeometry(0.18, 0.32, 24);
373
- const mat = new THREE.MeshBasicMaterial({
374
- color: 0x0ea5e9,
375
- transparent: true,
376
- opacity: 0.65,
377
- side: THREE.DoubleSide,
378
- depthWrite: false,
379
- });
380
- const ring = new THREE.Mesh(geo, mat);
381
- ring.rotation.x = -Math.PI / 2;
382
- ring.position.set(x, 0.31, z);
383
- this.scene.add(ring);
384
-
385
- let life = 0;
386
- const sys = {
387
- mesh: ring,
388
- update: (dt) => {
389
- life += dt;
390
- if (life >= 1.1) {
391
- this.scene.remove(ring);
392
- geo.dispose();
393
- mat.dispose();
394
- const idx = this.systems.indexOf(sys);
395
- if (idx >= 0) this.systems.splice(idx, 1);
396
- return;
397
- }
398
- ring.scale.setScalar(1 + life * 3.2);
399
- ring.material.opacity = Math.max(0, 0.65 * (1 - life / 1.1));
400
- },
401
- };
402
- this.systems.push(sys);
403
- }
404
-
405
- _triggerPulse(x, y, z, colorHex, lift = 1, delayMs = 0) {
406
- const spawn = () => {
407
- const count = 38;
408
- const positions = new Float32Array(count * 3);
409
- const velocities = new Float32Array(count * 3);
410
-
411
- for (let i = 0; i < count; i++) {
412
- positions[i * 3] = x;
413
- positions[i * 3 + 1] = y;
414
- positions[i * 3 + 2] = z;
415
-
416
- const a = (i / count) * Math.PI * 2;
417
- const speed = 0.8 + Math.random() * 1.4;
418
- velocities[i * 3] = Math.cos(a) * speed;
419
- velocities[i * 3 + 1] = 0.8 + Math.random() * lift;
420
- velocities[i * 3 + 2] = Math.sin(a) * speed;
421
- }
422
-
423
- const geo = new THREE.BufferGeometry();
424
- geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
425
- const mat = new THREE.PointsMaterial({
426
- size: 0.09,
427
- color: colorHex,
428
- transparent: true,
429
- opacity: 0.92,
430
- blending: THREE.AdditiveBlending,
431
- depthWrite: false,
432
- });
433
- const points = new THREE.Points(geo, mat);
434
- this.scene.add(points);
435
-
436
- let life = 0;
437
- const ttl = 0.68;
438
- const sys = {
439
- mesh: points,
440
- update: (dt) => {
441
- life += dt;
442
- if (life >= ttl) {
443
- this.scene.remove(points);
444
- geo.dispose();
445
- mat.dispose();
446
- const idx = this.systems.indexOf(sys);
447
- if (idx >= 0) this.systems.splice(idx, 1);
448
- return;
449
- }
450
-
451
- const arr = geo.attributes.position.array;
452
- for (let i = 0; i < count; i++) {
453
- arr[i * 3] += velocities[i * 3] * dt;
454
- arr[i * 3 + 1] += velocities[i * 3 + 1] * dt;
455
- arr[i * 3 + 2] += velocities[i * 3 + 2] * dt;
456
- velocities[i * 3 + 1] -= 2.8 * dt;
457
- }
458
- geo.attributes.position.needsUpdate = true;
459
- mat.opacity = Math.max(0, 0.92 - (life / ttl) * 0.92);
460
- },
461
- };
462
-
463
- this.systems.push(sys);
464
- };
465
-
466
- if (delayMs > 0) {
467
- setTimeout(spawn, delayMs);
468
- } else {
469
- spawn();
470
- }
471
- }
472
-
473
- dispose() {
474
- for (const system of this.systems) {
475
- if (system.mesh) {
476
- this.scene.remove(system.mesh);
477
- disposeObject3D(system.mesh);
478
- }
479
- }
480
- this.systems = [];
481
- }
482
- }