@holoscript/engine 6.0.3 → 6.0.4
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/AutoMesher-CK47F6AV.js +17 -0
- package/dist/GPUBuffers-2LHBCD7X.js +9 -0
- package/dist/WebGPUContext-TNEUYU2Y.js +11 -0
- package/dist/animation/index.cjs +38 -38
- package/dist/animation/index.d.cts +1 -1
- package/dist/animation/index.d.ts +1 -1
- package/dist/animation/index.js +1 -1
- package/dist/audio/index.cjs +16 -6
- package/dist/audio/index.d.cts +1 -1
- package/dist/audio/index.d.ts +1 -1
- package/dist/audio/index.js +1 -1
- package/dist/camera/index.cjs +23 -23
- package/dist/camera/index.d.cts +1 -1
- package/dist/camera/index.d.ts +1 -1
- package/dist/camera/index.js +1 -1
- package/dist/character/index.cjs +6 -4
- package/dist/character/index.js +1 -1
- package/dist/choreography/index.cjs +1194 -0
- package/dist/choreography/index.d.cts +687 -0
- package/dist/choreography/index.d.ts +687 -0
- package/dist/choreography/index.js +1156 -0
- package/dist/chunk-2CSNRI2N.js +217 -0
- package/dist/chunk-33T2WINR.js +266 -0
- package/dist/chunk-35R73OFM.js +1257 -0
- package/dist/chunk-4MMDSUNP.js +1256 -0
- package/dist/chunk-5V6HOU72.js +319 -0
- package/dist/chunk-6QOP6PYF.js +1038 -0
- package/dist/chunk-7KMJVHIL.js +8944 -0
- package/dist/chunk-7VPUC62U.js +1106 -0
- package/dist/chunk-A2Y6RCAT.js +1878 -0
- package/dist/chunk-AHM42MK6.js +8944 -0
- package/dist/chunk-BL7IDTHE.js +218 -0
- package/dist/chunk-CITOMSWL.js +10462 -0
- package/dist/chunk-CXDPKW2K.js +8944 -0
- package/dist/chunk-CXZPLD4S.js +223 -0
- package/dist/chunk-CZYJE7IH.js +5169 -0
- package/dist/chunk-D2OP7YC7.js +6325 -0
- package/dist/chunk-EDRVQHUU.js +1544 -0
- package/dist/chunk-EJSLOOW2.js +3589 -0
- package/dist/chunk-F53SFGW5.js +1878 -0
- package/dist/chunk-HCFPELPY.js +919 -0
- package/dist/chunk-HNEE36PY.js +93 -0
- package/dist/chunk-HYXNV36F.js +1256 -0
- package/dist/chunk-IB7KHVFY.js +821 -0
- package/dist/chunk-IBBO7YYG.js +690 -0
- package/dist/chunk-ILIBGINU.js +5470 -0
- package/dist/chunk-IS4MHLKN.js +5479 -0
- package/dist/chunk-JT2PFKWD.js +5479 -0
- package/dist/chunk-K4CUB4NY.js +1038 -0
- package/dist/chunk-KATDQXRJ.js +10462 -0
- package/dist/chunk-KBQE6ZFJ.js +8944 -0
- package/dist/chunk-KBVD5K7E.js +560 -0
- package/dist/chunk-KCDPVQRY.js +4088 -0
- package/dist/chunk-KN4QJPKN.js +8944 -0
- package/dist/chunk-KWJ3ROSI.js +8944 -0
- package/dist/chunk-L45VF6DD.js +919 -0
- package/dist/chunk-LY4T37YK.js +307 -0
- package/dist/chunk-MDN5WZXA.js +1544 -0
- package/dist/chunk-MGCDP6VU.js +928 -0
- package/dist/chunk-NCX7X6G2.js +8681 -0
- package/dist/chunk-OF54BPVD.js +913 -0
- package/dist/chunk-OWSN2Q3Q.js +690 -0
- package/dist/chunk-PRRB5TTA.js +406 -0
- package/dist/chunk-PXWVQF76.js +4086 -0
- package/dist/chunk-PYCOIDT2.js +812 -0
- package/dist/chunk-PZCSADOV.js +928 -0
- package/dist/chunk-Q2XBVS2K.js +1038 -0
- package/dist/chunk-QDZRXWN5.js +1776 -0
- package/dist/chunk-RNWOZ6WQ.js +913 -0
- package/dist/chunk-ROLFT4CJ.js +1693 -0
- package/dist/chunk-SLTJRZ2N.js +266 -0
- package/dist/chunk-SRUS5XSU.js +4088 -0
- package/dist/chunk-TKCA3WZ5.js +5409 -0
- package/dist/chunk-TNRMXYI2.js +1650 -0
- package/dist/chunk-TQB3GJGM.js +9763 -0
- package/dist/chunk-TUFGXG6K.js +510 -0
- package/dist/chunk-U6KMTGQJ.js +632 -0
- package/dist/chunk-VMGJQST6.js +8681 -0
- package/dist/chunk-X4F4TCG4.js +5470 -0
- package/dist/chunk-ZIFROE75.js +1544 -0
- package/dist/chunk-ZIJQYHSQ.js +1204 -0
- package/dist/combat/index.cjs +4 -4
- package/dist/combat/index.d.cts +1 -1
- package/dist/combat/index.d.ts +1 -1
- package/dist/combat/index.js +1 -1
- package/dist/ecs/index.cjs +1 -1
- package/dist/ecs/index.js +1 -1
- package/dist/environment/index.cjs +14 -14
- package/dist/environment/index.d.cts +1 -1
- package/dist/environment/index.d.ts +1 -1
- package/dist/environment/index.js +1 -1
- package/dist/gpu/index.cjs +4810 -0
- package/dist/gpu/index.js +3714 -0
- package/dist/hologram/index.cjs +27 -1
- package/dist/hologram/index.js +1 -1
- package/dist/index-B2PIsAmR.d.cts +2180 -0
- package/dist/index-B2PIsAmR.d.ts +2180 -0
- package/dist/index-BHySEPX7.d.cts +2921 -0
- package/dist/index-BJV21zuy.d.cts +341 -0
- package/dist/index-BJV21zuy.d.ts +341 -0
- package/dist/index-BQutTphC.d.cts +790 -0
- package/dist/index-ByIq2XrS.d.cts +3910 -0
- package/dist/index-BysHjDSO.d.cts +224 -0
- package/dist/index-BysHjDSO.d.ts +224 -0
- package/dist/index-CKwAJGck.d.ts +455 -0
- package/dist/index-CUl3QstQ.d.cts +3006 -0
- package/dist/index-CUl3QstQ.d.ts +3006 -0
- package/dist/index-CmYtNiI-.d.cts +953 -0
- package/dist/index-CmYtNiI-.d.ts +953 -0
- package/dist/index-CnRzWxi_.d.cts +522 -0
- package/dist/index-CnRzWxi_.d.ts +522 -0
- package/dist/index-CwRWbSC7.d.ts +2921 -0
- package/dist/index-CxKIBstO.d.ts +790 -0
- package/dist/index-DJ6-R8vh.d.cts +455 -0
- package/dist/index-DQKisbcI.d.cts +4968 -0
- package/dist/index-DQKisbcI.d.ts +4968 -0
- package/dist/index-DRT2zJez.d.ts +3910 -0
- package/dist/index-DfNLiAka.d.cts +192 -0
- package/dist/index-DfNLiAka.d.ts +192 -0
- package/dist/index-nMvkoRm8.d.cts +405 -0
- package/dist/index-nMvkoRm8.d.ts +405 -0
- package/dist/index-s9yOFU37.d.cts +604 -0
- package/dist/index-s9yOFU37.d.ts +604 -0
- package/dist/index.cjs +22966 -6960
- package/dist/index.d.cts +864 -20
- package/dist/index.d.ts +864 -20
- package/dist/index.js +3062 -48
- package/dist/input/index.cjs +1 -1
- package/dist/input/index.js +1 -1
- package/dist/orbital/index.cjs +3 -3
- package/dist/orbital/index.d.cts +1 -1
- package/dist/orbital/index.d.ts +1 -1
- package/dist/orbital/index.js +1 -1
- package/dist/particles/index.cjs +16 -16
- package/dist/particles/index.d.cts +1 -1
- package/dist/particles/index.d.ts +1 -1
- package/dist/particles/index.js +1 -1
- package/dist/physics/index.cjs +2377 -21
- package/dist/physics/index.d.cts +1 -1
- package/dist/physics/index.d.ts +1 -1
- package/dist/physics/index.js +35 -1
- package/dist/postfx/index.cjs +3491 -0
- package/dist/postfx/index.js +93 -0
- package/dist/procedural/index.cjs +1 -1
- package/dist/procedural/index.js +1 -1
- package/dist/puppeteer-5VF6KDVO.js +52197 -0
- package/dist/puppeteer-IZVZ3SG4.js +52197 -0
- package/dist/rendering/index.cjs +33 -32
- package/dist/rendering/index.d.cts +1 -1
- package/dist/rendering/index.d.ts +1 -1
- package/dist/rendering/index.js +8 -6
- package/dist/runtime/index.cjs +23 -13
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +8 -6
- package/dist/runtime/protocols/index.cjs +349 -0
- package/dist/runtime/protocols/index.js +15 -0
- package/dist/scene/index.cjs +8 -8
- package/dist/scene/index.d.cts +1 -1
- package/dist/scene/index.d.ts +1 -1
- package/dist/scene/index.js +1 -1
- package/dist/shader/index.cjs +3087 -0
- package/dist/shader/index.js +3044 -0
- package/dist/simulation/index.cjs +10680 -0
- package/dist/simulation/index.d.cts +3 -0
- package/dist/simulation/index.d.ts +3 -0
- package/dist/simulation/index.js +307 -0
- package/dist/spatial/index.cjs +2443 -0
- package/dist/spatial/index.d.cts +1545 -0
- package/dist/spatial/index.d.ts +1545 -0
- package/dist/spatial/index.js +2400 -0
- package/dist/terrain/index.cjs +1 -1
- package/dist/terrain/index.d.cts +1 -1
- package/dist/terrain/index.d.ts +1 -1
- package/dist/terrain/index.js +1 -1
- package/dist/transformers.node-4NKAPD5U.js +45620 -0
- package/dist/vm/index.cjs +7 -8
- package/dist/vm/index.d.cts +1 -1
- package/dist/vm/index.d.ts +1 -1
- package/dist/vm/index.js +1 -1
- package/dist/vm-bridge/index.cjs +2 -2
- package/dist/vm-bridge/index.d.cts +2 -2
- package/dist/vm-bridge/index.d.ts +2 -2
- package/dist/vm-bridge/index.js +1 -1
- package/dist/vr/index.cjs +6 -6
- package/dist/vr/index.js +1 -1
- package/dist/world/index.cjs +3 -3
- package/dist/world/index.d.cts +1 -1
- package/dist/world/index.d.ts +1 -1
- package/dist/world/index.js +1 -1
- package/package.json +53 -21
- package/LICENSE +0 -21
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
// src/gpu/WebGPUContext.ts
|
|
2
|
+
var WebGPUContext = class {
|
|
3
|
+
adapter = null;
|
|
4
|
+
device = null;
|
|
5
|
+
limits = null;
|
|
6
|
+
features = /* @__PURE__ */ new Set();
|
|
7
|
+
options;
|
|
8
|
+
initialized = false;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = {
|
|
11
|
+
powerPreference: options.powerPreference ?? "high-performance",
|
|
12
|
+
requiredFeatures: options.requiredFeatures ?? [],
|
|
13
|
+
requiredLimits: options.requiredLimits ?? {},
|
|
14
|
+
fallbackToCPU: options.fallbackToCPU ?? true
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initialize WebGPU context
|
|
19
|
+
*
|
|
20
|
+
* @returns Promise that resolves when initialization is complete
|
|
21
|
+
* @throws Error if WebGPU is not supported and fallbackToCPU is false
|
|
22
|
+
*/
|
|
23
|
+
async initialize() {
|
|
24
|
+
if (this.initialized) {
|
|
25
|
+
console.warn("WebGPUContext already initialized");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (!("gpu" in navigator)) {
|
|
29
|
+
this.handleUnsupported("WebGPU not supported in this browser");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
this.adapter = await navigator.gpu.requestAdapter({
|
|
34
|
+
powerPreference: this.options.powerPreference
|
|
35
|
+
});
|
|
36
|
+
if (!this.adapter) {
|
|
37
|
+
this.handleUnsupported("Failed to get WebGPU adapter");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.limits = this.adapter.limits;
|
|
41
|
+
this.features = new Set(this.adapter.features);
|
|
42
|
+
const missingFeatures = this.options.requiredFeatures.filter(
|
|
43
|
+
(feature) => !this.features.has(feature)
|
|
44
|
+
);
|
|
45
|
+
if (missingFeatures.length > 0) {
|
|
46
|
+
throw new Error(`Missing required WebGPU features: ${missingFeatures.join(", ")}`);
|
|
47
|
+
}
|
|
48
|
+
const deviceDescriptor = {
|
|
49
|
+
requiredFeatures: this.options.requiredFeatures,
|
|
50
|
+
requiredLimits: this.options.requiredLimits
|
|
51
|
+
};
|
|
52
|
+
this.device = await this.adapter.requestDevice(deviceDescriptor);
|
|
53
|
+
this.device.lost.then((info) => {
|
|
54
|
+
console.error("WebGPU device lost:", info.message, info.reason);
|
|
55
|
+
if (info.reason !== "destroyed") {
|
|
56
|
+
this.handleDeviceLost(info);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
this.device.addEventListener("uncapturederror", (event) => {
|
|
60
|
+
console.error("WebGPU uncaptured error:", event.error);
|
|
61
|
+
});
|
|
62
|
+
this.initialized = true;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
this.handleUnsupported(`WebGPU initialization failed: ${error}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if WebGPU is supported and initialized
|
|
69
|
+
*/
|
|
70
|
+
isSupported() {
|
|
71
|
+
return this.initialized && this.device !== null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get WebGPU device
|
|
75
|
+
* @throws Error if device is not initialized
|
|
76
|
+
*/
|
|
77
|
+
getDevice() {
|
|
78
|
+
if (!this.device) {
|
|
79
|
+
throw new Error("WebGPU device not initialized. Call initialize() first.");
|
|
80
|
+
}
|
|
81
|
+
return this.device;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get WebGPU adapter
|
|
85
|
+
* @throws Error if adapter is not available
|
|
86
|
+
*/
|
|
87
|
+
getAdapter() {
|
|
88
|
+
if (!this.adapter) {
|
|
89
|
+
throw new Error("WebGPU adapter not available");
|
|
90
|
+
}
|
|
91
|
+
return this.adapter;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get device limits
|
|
95
|
+
*/
|
|
96
|
+
getLimits() {
|
|
97
|
+
if (!this.limits) {
|
|
98
|
+
throw new Error("WebGPU limits not available");
|
|
99
|
+
}
|
|
100
|
+
return this.limits;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get supported features
|
|
104
|
+
*/
|
|
105
|
+
getFeatures() {
|
|
106
|
+
return this.features;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if a specific feature is supported
|
|
110
|
+
*/
|
|
111
|
+
hasFeature(feature) {
|
|
112
|
+
return this.features.has(feature);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get capabilities object
|
|
116
|
+
*/
|
|
117
|
+
getCapabilities() {
|
|
118
|
+
return {
|
|
119
|
+
supported: this.isSupported(),
|
|
120
|
+
adapter: this.adapter,
|
|
121
|
+
device: this.device,
|
|
122
|
+
limits: this.limits,
|
|
123
|
+
features: this.features
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get optimal workgroup size for compute shaders
|
|
128
|
+
*
|
|
129
|
+
* Returns a workgroup size that maximizes occupancy based on device limits.
|
|
130
|
+
* Common values: 64, 128, 256 (must be power of 2)
|
|
131
|
+
*/
|
|
132
|
+
getOptimalWorkgroupSize() {
|
|
133
|
+
if (!this.limits) return 256;
|
|
134
|
+
const maxInvocations = this.limits.maxComputeInvocationsPerWorkgroup;
|
|
135
|
+
if (maxInvocations >= 256) return 256;
|
|
136
|
+
if (maxInvocations >= 128) return 128;
|
|
137
|
+
if (maxInvocations >= 64) return 64;
|
|
138
|
+
return 32;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Cleanup resources
|
|
142
|
+
*/
|
|
143
|
+
destroy() {
|
|
144
|
+
if (this.device) {
|
|
145
|
+
this.device.destroy();
|
|
146
|
+
this.device = null;
|
|
147
|
+
}
|
|
148
|
+
this.adapter = null;
|
|
149
|
+
this.limits = null;
|
|
150
|
+
this.features.clear();
|
|
151
|
+
this.initialized = false;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Handle unsupported browser/device
|
|
155
|
+
*/
|
|
156
|
+
handleUnsupported(reason) {
|
|
157
|
+
console.warn(`\u26A0\uFE0F ${reason}`);
|
|
158
|
+
if (!this.options.fallbackToCPU) {
|
|
159
|
+
throw new Error(`WebGPU required but not available: ${reason}`);
|
|
160
|
+
}
|
|
161
|
+
console.warn("\u{1F4A1} Falling back to CPU-based physics simulation");
|
|
162
|
+
this.initialized = false;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Handle device lost event
|
|
166
|
+
*/
|
|
167
|
+
handleDeviceLost(_info) {
|
|
168
|
+
console.error("WebGPU device lost, attempting to recreate...");
|
|
169
|
+
this.initialized = false;
|
|
170
|
+
this.initialize().catch((error) => {
|
|
171
|
+
console.error("Failed to reinitialize WebGPU device:", error);
|
|
172
|
+
if (this.options.fallbackToCPU) {
|
|
173
|
+
console.warn("Falling back to CPU physics");
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Detect and log GPU information (for debugging)
|
|
179
|
+
*/
|
|
180
|
+
async logGPUInfo() {
|
|
181
|
+
if (!this.adapter) {
|
|
182
|
+
console.warn("No adapter available");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const info = await this.adapter.requestAdapterInfo?.();
|
|
186
|
+
if (info) {
|
|
187
|
+
void info;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
var globalContext = null;
|
|
192
|
+
function getGlobalWebGPUContext(options) {
|
|
193
|
+
if (!globalContext) {
|
|
194
|
+
globalContext = new WebGPUContext(options);
|
|
195
|
+
}
|
|
196
|
+
return globalContext;
|
|
197
|
+
}
|
|
198
|
+
async function createPhysicsSimulation(options) {
|
|
199
|
+
if (options.preferGPU !== false) {
|
|
200
|
+
try {
|
|
201
|
+
const context = new WebGPUContext({ fallbackToCPU: true });
|
|
202
|
+
await context.initialize();
|
|
203
|
+
if (context.isSupported()) {
|
|
204
|
+
return { usingGPU: true, context };
|
|
205
|
+
}
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.warn("GPU initialization failed, using CPU fallback:", error);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { usingGPU: false };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export {
|
|
214
|
+
WebGPUContext,
|
|
215
|
+
getGlobalWebGPUContext,
|
|
216
|
+
createPhysicsSimulation
|
|
217
|
+
};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./chunk-AKLW2MUS.js";
|
|
4
|
+
|
|
5
|
+
// src/vm-bridge/index.ts
|
|
6
|
+
var vm_bridge_exports = {};
|
|
7
|
+
__export(vm_bridge_exports, {
|
|
8
|
+
SpatialCognitiveAgent: () => SpatialCognitiveAgent,
|
|
9
|
+
applyActions: () => applyActions,
|
|
10
|
+
captureSceneSnapshot: () => captureSceneSnapshot
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// src/vm-bridge/bridge.ts
|
|
14
|
+
import { UAALOpCode, UAALCompiler } from "@holoscript/uaal";
|
|
15
|
+
function captureSceneSnapshot(world) {
|
|
16
|
+
const entities = [];
|
|
17
|
+
for (const entity of world.getAllEntities()) {
|
|
18
|
+
const snapshot = {
|
|
19
|
+
id: entity.id,
|
|
20
|
+
name: entity.name,
|
|
21
|
+
parentId: entity.parentId,
|
|
22
|
+
childIds: [...entity.childIds],
|
|
23
|
+
traits: [...entity.traits]
|
|
24
|
+
};
|
|
25
|
+
const transform = world.getComponent(entity.id, 1);
|
|
26
|
+
if (transform) snapshot.transform = transform;
|
|
27
|
+
const geometry = world.getComponent(entity.id, 2);
|
|
28
|
+
if (geometry) snapshot.geometry = geometry;
|
|
29
|
+
const material = world.getComponent(entity.id, 3);
|
|
30
|
+
if (material) snapshot.material = material;
|
|
31
|
+
const rigidBody = world.getComponent(entity.id, 4);
|
|
32
|
+
if (rigidBody) snapshot.rigidBody = rigidBody;
|
|
33
|
+
entities.push(snapshot);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
entityCount: entities.length,
|
|
37
|
+
entities,
|
|
38
|
+
timestamp: Date.now()
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function applyActions(world, actions) {
|
|
42
|
+
const spawnedIds = [];
|
|
43
|
+
for (const action of actions) {
|
|
44
|
+
switch (action.type) {
|
|
45
|
+
case "spawn": {
|
|
46
|
+
const id = world.spawn(action.name);
|
|
47
|
+
if (action.position) {
|
|
48
|
+
world.setComponent(id, 1, {
|
|
49
|
+
// ComponentType.Transform
|
|
50
|
+
position: action.position,
|
|
51
|
+
rotation: { x: 0, y: 0, z: 0, w: 1 },
|
|
52
|
+
scale: { x: 1, y: 1, z: 1 }
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (action.geometryType !== void 0) {
|
|
56
|
+
world.setComponent(id, 2, { type: action.geometryType, params: {} });
|
|
57
|
+
}
|
|
58
|
+
spawnedIds.push(id);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case "despawn":
|
|
62
|
+
world.despawn(action.entityId);
|
|
63
|
+
break;
|
|
64
|
+
case "move": {
|
|
65
|
+
const existing = world.getComponent(action.entityId, 1);
|
|
66
|
+
const transform = existing ?? {
|
|
67
|
+
position: { x: 0, y: 0, z: 0 },
|
|
68
|
+
rotation: { x: 0, y: 0, z: 0, w: 1 },
|
|
69
|
+
scale: { x: 1, y: 1, z: 1 }
|
|
70
|
+
};
|
|
71
|
+
transform.position = action.position;
|
|
72
|
+
world.setComponent(action.entityId, 1, transform);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case "setComponent":
|
|
76
|
+
world.setComponent(action.entityId, action.componentType, action.data);
|
|
77
|
+
break;
|
|
78
|
+
case "applyTrait": {
|
|
79
|
+
const entity = world.getEntity(action.entityId);
|
|
80
|
+
if (entity) {
|
|
81
|
+
entity.traits.add(action.traitId);
|
|
82
|
+
entity.dirty = true;
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "removeTrait": {
|
|
87
|
+
const entity = world.getEntity(action.entityId);
|
|
88
|
+
if (entity) {
|
|
89
|
+
entity.traits.delete(action.traitId);
|
|
90
|
+
entity.dirty = true;
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return spawnedIds;
|
|
97
|
+
}
|
|
98
|
+
var SpatialCognitiveAgent = class {
|
|
99
|
+
world;
|
|
100
|
+
cognitiveVM;
|
|
101
|
+
compiler;
|
|
102
|
+
config;
|
|
103
|
+
lastCognitiveTickMs = -Infinity;
|
|
104
|
+
cognitiveIntervalMs;
|
|
105
|
+
pendingActions = [];
|
|
106
|
+
lastSnapshot = null;
|
|
107
|
+
tickCount = 0;
|
|
108
|
+
constructor(world, cognitiveVM, config = {}) {
|
|
109
|
+
this.world = world;
|
|
110
|
+
this.cognitiveVM = cognitiveVM;
|
|
111
|
+
this.compiler = new UAALCompiler();
|
|
112
|
+
this.config = {
|
|
113
|
+
cognitiveHz: config.cognitiveHz ?? 2,
|
|
114
|
+
enableLogging: config.enableLogging ?? false,
|
|
115
|
+
maxActionsPerTick: config.maxActionsPerTick ?? 50
|
|
116
|
+
};
|
|
117
|
+
this.cognitiveIntervalMs = 1e3 / this.config.cognitiveHz;
|
|
118
|
+
this.cognitiveVM.registerHandler(UAALOpCode.INTAKE, async (proxy) => {
|
|
119
|
+
const snapshot = this.perceive();
|
|
120
|
+
proxy.push(snapshot);
|
|
121
|
+
});
|
|
122
|
+
this.cognitiveVM.registerHandler(UAALOpCode.EXECUTE, async (proxy) => {
|
|
123
|
+
const actions = this.pendingActions.splice(0, this.config.maxActionsPerTick);
|
|
124
|
+
const spawned = this.mutate(actions);
|
|
125
|
+
proxy.push({
|
|
126
|
+
executed: true,
|
|
127
|
+
actionsApplied: actions.length,
|
|
128
|
+
spawnedIds: spawned
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
this.cognitiveVM.registerHandler(UAALOpCode.OP_EXECUTE_HOLOSCRIPT, async (proxy) => {
|
|
132
|
+
proxy.push(this.perceive());
|
|
133
|
+
});
|
|
134
|
+
this.cognitiveVM.registerHandler(
|
|
135
|
+
UAALOpCode.OP_SPATIAL_ANCHOR,
|
|
136
|
+
async (proxy, operands) => {
|
|
137
|
+
const name = operands?.[0] ?? "anchor";
|
|
138
|
+
const x = operands?.[1] ?? 0;
|
|
139
|
+
const y = operands?.[2] ?? 0;
|
|
140
|
+
const z = operands?.[3] ?? 0;
|
|
141
|
+
const id = this.world.spawn(name);
|
|
142
|
+
this.world.setComponent(id, 1, {
|
|
143
|
+
// ComponentType.Transform
|
|
144
|
+
position: { x, y, z },
|
|
145
|
+
rotation: { x: 0, y: 0, z: 0, w: 1 },
|
|
146
|
+
scale: { x: 1, y: 1, z: 1 }
|
|
147
|
+
});
|
|
148
|
+
proxy.push(id);
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
this.cognitiveVM.registerHandler(
|
|
152
|
+
UAALOpCode.OP_RENDER_HOLOGRAM,
|
|
153
|
+
async (proxy, operands) => {
|
|
154
|
+
const entityId = operands?.[0] ?? 0;
|
|
155
|
+
const geoType = operands?.[1] ?? 0;
|
|
156
|
+
const color = operands?.[2] ?? 65535;
|
|
157
|
+
this.world.setComponent(entityId, 2, { type: geoType, params: {} });
|
|
158
|
+
this.world.setComponent(entityId, 3, {
|
|
159
|
+
color,
|
|
160
|
+
metalness: 0.3,
|
|
161
|
+
roughness: 0.4,
|
|
162
|
+
emissive: 0,
|
|
163
|
+
opacity: 0.8
|
|
164
|
+
});
|
|
165
|
+
proxy.push({ rendered: true, entityId });
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
this.cognitiveVM.registerHandler(
|
|
169
|
+
UAALOpCode.OP_VR_TELEPORT,
|
|
170
|
+
async (proxy, operands) => {
|
|
171
|
+
const entityId = operands?.[0] ?? 0;
|
|
172
|
+
const x = operands?.[1] ?? 0;
|
|
173
|
+
const y = operands?.[2] ?? 0;
|
|
174
|
+
const z = operands?.[3] ?? 0;
|
|
175
|
+
this.world.setComponent(entityId, 1, {
|
|
176
|
+
// ComponentType.Transform
|
|
177
|
+
position: { x, y, z },
|
|
178
|
+
rotation: { x: 0, y: 0, z: 0, w: 1 },
|
|
179
|
+
scale: { x: 1, y: 1, z: 1 }
|
|
180
|
+
});
|
|
181
|
+
proxy.push({ teleported: true, entityId, position: { x, y, z } });
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
if (this.config.enableLogging) {
|
|
185
|
+
console.log(`[vm-bridge] Agent initialized (cognitive: ${this.config.cognitiveHz}Hz)`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// ── Core API ──────────────────────────────────────────────────────────────
|
|
189
|
+
/**
|
|
190
|
+
* Snapshot the ECS world for agent perception
|
|
191
|
+
*/
|
|
192
|
+
perceive() {
|
|
193
|
+
this.lastSnapshot = captureSceneSnapshot(this.world);
|
|
194
|
+
return this.lastSnapshot;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Run a cognitive cycle (7-phase) with the current scene as context
|
|
198
|
+
*/
|
|
199
|
+
async decide(task) {
|
|
200
|
+
const bytecode = this.compiler.buildFullCycle(task);
|
|
201
|
+
const result = await this.cognitiveVM.execute(bytecode, {
|
|
202
|
+
task,
|
|
203
|
+
sceneEntityCount: this.world.entityCount,
|
|
204
|
+
timestamp: Date.now()
|
|
205
|
+
});
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Apply agent actions to the ECS world
|
|
210
|
+
*/
|
|
211
|
+
mutate(actions) {
|
|
212
|
+
return applyActions(this.world, actions);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Queue actions for the next cognitive tick
|
|
216
|
+
*/
|
|
217
|
+
queueAction(action) {
|
|
218
|
+
this.pendingActions.push(action);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Queue multiple actions
|
|
222
|
+
*/
|
|
223
|
+
queueActions(actions) {
|
|
224
|
+
this.pendingActions.push(...actions);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Main tick — called each frame. Runs cognitive cycle at configured frequency.
|
|
228
|
+
* Returns whether a cognitive tick was performed.
|
|
229
|
+
*/
|
|
230
|
+
async tick(currentTimeMs) {
|
|
231
|
+
this.tickCount++;
|
|
232
|
+
const elapsed = currentTimeMs - this.lastCognitiveTickMs;
|
|
233
|
+
if (elapsed < this.cognitiveIntervalMs) {
|
|
234
|
+
return { perceived: false, decided: false, actionsApplied: 0 };
|
|
235
|
+
}
|
|
236
|
+
this.lastCognitiveTickMs = currentTimeMs;
|
|
237
|
+
const snapshot = this.perceive();
|
|
238
|
+
const cycleResult = await this.decide(`Tick ${this.tickCount}: observe and act`);
|
|
239
|
+
const actions = this.pendingActions.splice(0, this.config.maxActionsPerTick);
|
|
240
|
+
const _spawned = this.mutate(actions);
|
|
241
|
+
return {
|
|
242
|
+
perceived: true,
|
|
243
|
+
decided: true,
|
|
244
|
+
actionsApplied: actions.length,
|
|
245
|
+
sceneSnapshot: snapshot,
|
|
246
|
+
cycleResult
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// ── Accessors ─────────────────────────────────────────────────────────────
|
|
250
|
+
getLastSnapshot() {
|
|
251
|
+
return this.lastSnapshot;
|
|
252
|
+
}
|
|
253
|
+
getPendingActionCount() {
|
|
254
|
+
return this.pendingActions.length;
|
|
255
|
+
}
|
|
256
|
+
getTickCount() {
|
|
257
|
+
return this.tickCount;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export {
|
|
262
|
+
captureSceneSnapshot,
|
|
263
|
+
applyActions,
|
|
264
|
+
SpatialCognitiveAgent,
|
|
265
|
+
vm_bridge_exports
|
|
266
|
+
};
|