@auraindustry/aurajs 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 +7 -0
- package/benchmarks/perf-thresholds.json +27 -0
- package/package.json +6 -1
- package/src/ai-guidance.mjs +302 -0
- package/src/authored-project.mjs +498 -2
- package/src/build-contract/capabilities.mjs +87 -1
- package/src/build-contract/constants.mjs +1 -0
- package/src/build-contract.mjs +2 -0
- package/src/bundler.mjs +143 -13
- package/src/cli.mjs +681 -13
- package/src/commands/packs.mjs +741 -0
- package/src/commands/project-authoring.mjs +128 -1
- package/src/conformance/cases/app-and-ui-runtime-cases.mjs +1 -2
- package/src/conformance/cases/core-runtime-cases.mjs +6 -2
- package/src/conformance/cases/scene3d-and-media-cases.mjs +238 -0
- package/src/conformance/cases/systems-and-gameplay-cases.mjs +265 -4
- package/src/conformance-mobile.mjs +166 -0
- package/src/conformance.mjs +89 -30
- package/src/evidence-bundle.mjs +242 -0
- package/src/headless-test/runtime-coordinator.mjs +186 -33
- package/src/headless-test.mjs +2 -0
- package/src/helpers/2d/index.mjs +183 -0
- package/src/helpers/index.mjs +26 -0
- package/src/helpers/starter-utils/adventure-objectives.js +102 -0
- package/src/helpers/starter-utils/adventure-world-2d.js +221 -0
- package/src/helpers/starter-utils/animation-2d.js +337 -0
- package/src/helpers/starter-utils/animation-packaging-2d.js +203 -0
- package/src/helpers/starter-utils/atlas-assets-2d.js +111 -0
- package/src/helpers/starter-utils/autoplay-debug-2d.js +215 -0
- package/src/helpers/starter-utils/avatar-3d.js +404 -0
- package/src/helpers/starter-utils/combat-feedback-2d.js +320 -0
- package/src/helpers/starter-utils/combat-runtime-2d.js +290 -0
- package/src/helpers/starter-utils/core.js +150 -0
- package/src/helpers/starter-utils/dialogue-2d.js +351 -0
- package/src/helpers/starter-utils/enemy-archetypes-2d.js +68 -0
- package/src/helpers/starter-utils/index.js +26 -0
- package/src/helpers/starter-utils/inventory-2d.js +268 -0
- package/src/helpers/starter-utils/journal-2d.js +267 -0
- package/src/helpers/starter-utils/platformer-3d.js +132 -0
- package/src/helpers/starter-utils/scene-audio-2d.js +236 -0
- package/src/helpers/starter-utils/streamed-world-2d.js +378 -0
- package/src/helpers/starter-utils/tilemap-nav-2d.js +499 -0
- package/src/helpers/starter-utils/tilemap-world-2d.js +205 -0
- package/src/helpers/starter-utils/triggers.js +662 -0
- package/src/helpers/starter-utils/tween-2d.js +615 -0
- package/src/helpers/starter-utils/wave-director.js +101 -0
- package/src/helpers/starter-utils/world-compositor-2d.js +253 -0
- package/src/helpers/starter-utils/world-persistence-2d.js +180 -0
- package/src/mobile/android/build.mjs +606 -0
- package/src/mobile/android/host-artifact.mjs +280 -0
- package/src/mobile/ios/build.mjs +1323 -0
- package/src/mobile/ios/host-artifact.mjs +819 -0
- package/src/mobile/shared/capabilities.mjs +174 -0
- package/src/packs/catalog.mjs +259 -0
- package/src/perf-benchmark-runner.mjs +17 -12
- package/src/perf-benchmark.mjs +408 -4
- package/src/publish-command.mjs +303 -6
- package/src/replay-runtime.mjs +257 -0
- package/src/scaffold/config.mjs +2 -0
- package/src/scaffold/fs.mjs +8 -1
- package/src/scaffold/project-docs.mjs +43 -1
- package/src/scaffold.mjs +4 -0
- package/src/session-runtime.mjs +4 -3
- package/src/web-conformance.mjs +0 -36
- package/templates/create/2d-adventure/config/gameplay/adventure.config.js +9 -6
- package/templates/create/2d-adventure/content/gameplay/dialogue.js +85 -0
- package/templates/create/2d-adventure/content/gameplay/world.js +32 -36
- package/templates/create/2d-adventure/content/gameplay/world.tilemap.json +273 -0
- package/templates/create/2d-adventure/docs/design/loop.md +4 -3
- package/templates/create/2d-adventure/prefabs/relic.prefab.js +10 -10
- package/templates/create/2d-adventure/prefabs/world.prefab.js +127 -74
- package/templates/create/2d-adventure/scenes/gameplay.scene.js +603 -112
- package/templates/create/2d-adventure/src/runtime/capabilities.js +16 -0
- package/templates/create/2d-adventure/ui/hud.screen.js +187 -4
- package/templates/create/2d-adventure/ui/journal.screen.js +183 -0
- package/templates/create/3d/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d/src/runtime/capabilities.js +5 -0
- package/templates/create/3d/src/runtime/materials.js +10 -0
- package/templates/create/3d-adventure/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d-adventure/src/runtime/capabilities.js +5 -0
- package/templates/create/3d-adventure/src/runtime/materials.js +11 -0
- package/templates/create/3d-collectathon/scenes/gameplay.scene.js +30 -3
- package/templates/create/3d-collectathon/src/runtime/capabilities.js +5 -0
- package/templates/create/3d-collectathon/src/runtime/materials.js +10 -0
- package/templates/create/shared/src/runtime/ui-forms.js +552 -0
- package/templates/create/shared/src/starter-utils/adventure-world-2d.js +221 -0
- package/templates/create/shared/src/starter-utils/animation-packaging-2d.js +203 -0
- package/templates/create/shared/src/starter-utils/atlas-assets-2d.js +111 -0
- package/templates/create/shared/src/starter-utils/autoplay-debug-2d.js +215 -0
- package/templates/create/shared/src/starter-utils/combat-runtime-2d.js +290 -0
- package/templates/create/shared/src/starter-utils/dialogue-2d.js +351 -0
- package/templates/create/shared/src/starter-utils/index.js +15 -1
- package/templates/create/shared/src/starter-utils/inventory-2d.js +268 -0
- package/templates/create/shared/src/starter-utils/journal-2d.js +267 -0
- package/templates/create/shared/src/starter-utils/scene-audio-2d.js +236 -0
- package/templates/create/shared/src/starter-utils/streamed-world-2d.js +378 -0
- package/templates/create/shared/src/starter-utils/tilemap-nav-2d.js +499 -0
- package/templates/create/shared/src/starter-utils/tilemap-world-2d.js +205 -0
- package/templates/create/shared/src/starter-utils/world-compositor-2d.js +253 -0
- package/templates/create/shared/src/starter-utils/world-persistence-2d.js +180 -0
- package/templates/create-bin/play.js +36 -7
- package/templates/skills/auramaxx/SKILL.md +46 -0
- package/templates/skills/auramaxx/project-requirements.md +68 -0
- package/templates/skills/auramaxx/starter-recipes.md +104 -0
- package/templates/skills/auramaxx/validation-checklist.md +49 -0
- package/templates/skills/aurajs/SKILL.md +0 -96
- package/templates/skills/aurajs/api-contract-3d.md +0 -7
- package/templates/skills/aurajs/api-contract.md +0 -7
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
1
2
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
3
4
|
|
|
4
5
|
import {
|
|
5
6
|
scaffold,
|
|
@@ -8,6 +9,8 @@ import {
|
|
|
8
9
|
listCreateTemplateAliasHints,
|
|
9
10
|
normalizeCreateTemplate,
|
|
10
11
|
} from '../scaffold.mjs';
|
|
12
|
+
import { PACKAGED_STARTER_UTILS_DIR } from '../scaffold/config.mjs';
|
|
13
|
+
import { listFiles } from '../scaffold/fs.mjs';
|
|
11
14
|
import { importThreeJsProject, parseFromArgs } from '../project-importer.mjs';
|
|
12
15
|
import { generateProjectFiles, listMakeKinds, listProjectMakeCatalog, listProjectMakeKinds } from '../make.mjs';
|
|
13
16
|
import {
|
|
@@ -31,6 +34,10 @@ export const MAKE_KIND_OPTION_LIST = listMakeKinds().join('|');
|
|
|
31
34
|
export const PREFAB_ROLE_OPTION_LIST = CANONICAL_PREFAB_ROLES.join('|');
|
|
32
35
|
export const MAKE_USAGE = `aura make <${MAKE_KIND_OPTION_LIST}> <name> [--role <${PREFAB_ROLE_OPTION_LIST}>]`;
|
|
33
36
|
export const MAKE_SUPPORTED_KINDS_HELP_TEXT = listMakeKinds().join(', ');
|
|
37
|
+
export const VENDOR_USAGE = 'aura vendor helpers [--force] [--json]';
|
|
38
|
+
|
|
39
|
+
const STARTER_UTILS_VENDOR_SOURCE_ROOT = PACKAGED_STARTER_UTILS_DIR;
|
|
40
|
+
const STARTER_UTILS_VENDOR_TARGET_ROOT = 'src/starter-utils';
|
|
34
41
|
|
|
35
42
|
function raiseCliError(errorHandler, message) {
|
|
36
43
|
if (typeof errorHandler === 'function') {
|
|
@@ -208,6 +215,94 @@ export function parseSimpleJsonFlag(args, commandName) {
|
|
|
208
215
|
return { json };
|
|
209
216
|
}
|
|
210
217
|
|
|
218
|
+
export function parseVendorArgs(args) {
|
|
219
|
+
let target = null;
|
|
220
|
+
let force = false;
|
|
221
|
+
let json = false;
|
|
222
|
+
|
|
223
|
+
for (const arg of args) {
|
|
224
|
+
if (arg === '--force') {
|
|
225
|
+
force = true;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (arg === '--json') {
|
|
229
|
+
json = true;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
if (arg.startsWith('--')) {
|
|
233
|
+
throw new Error(`Unknown option for vendor: ${arg}`);
|
|
234
|
+
}
|
|
235
|
+
if (target !== null) {
|
|
236
|
+
throw new Error(`Unexpected extra argument "${arg}". Usage: ${VENDOR_USAGE}`);
|
|
237
|
+
}
|
|
238
|
+
target = arg;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (target !== 'helpers') {
|
|
242
|
+
throw new Error(`Vendor currently supports only "helpers". Usage: ${VENDOR_USAGE}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return { target, force, json };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function assertAuraProjectRoot(cwd) {
|
|
249
|
+
if (!existsSync(resolve(cwd, 'aura.config.json'))) {
|
|
250
|
+
throw new Error('Missing aura.config.json in the current directory.');
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function vendorStarterUtils({ cwd, force = false }) {
|
|
255
|
+
assertAuraProjectRoot(cwd);
|
|
256
|
+
if (!existsSync(STARTER_UTILS_VENDOR_SOURCE_ROOT)) {
|
|
257
|
+
throw new Error(`Missing packaged starter utils source at ${STARTER_UTILS_VENDOR_SOURCE_ROOT}.`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const created = [];
|
|
261
|
+
const overwritten = [];
|
|
262
|
+
const skipped = [];
|
|
263
|
+
|
|
264
|
+
for (const relativePath of listFiles(STARTER_UTILS_VENDOR_SOURCE_ROOT)) {
|
|
265
|
+
const sourcePath = resolve(STARTER_UTILS_VENDOR_SOURCE_ROOT, relativePath);
|
|
266
|
+
const targetRelativePath = `${STARTER_UTILS_VENDOR_TARGET_ROOT}/${relativePath}`.replace(/\\/g, '/');
|
|
267
|
+
const targetPath = resolve(cwd, targetRelativePath);
|
|
268
|
+
const source = readFileSync(sourcePath, 'utf8');
|
|
269
|
+
|
|
270
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
271
|
+
if (existsSync(targetPath)) {
|
|
272
|
+
if (force) {
|
|
273
|
+
writeFileSync(targetPath, source, 'utf8');
|
|
274
|
+
overwritten.push(targetRelativePath);
|
|
275
|
+
} else {
|
|
276
|
+
skipped.push(targetRelativePath);
|
|
277
|
+
}
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
writeFileSync(targetPath, source, 'utf8');
|
|
282
|
+
created.push(targetRelativePath);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const reasonCode = overwritten.length > 0
|
|
286
|
+
? 'project_helpers_resynced'
|
|
287
|
+
: created.length > 0
|
|
288
|
+
? 'project_helpers_vendored'
|
|
289
|
+
: 'project_helpers_already_vendored';
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
schema: 'aurajs.vendor-helpers.v1',
|
|
293
|
+
ok: true,
|
|
294
|
+
reasonCode,
|
|
295
|
+
projectRoot: cwd,
|
|
296
|
+
helperSet: 'starter-utils',
|
|
297
|
+
sourceRoot: STARTER_UTILS_VENDOR_SOURCE_ROOT,
|
|
298
|
+
targetRoot: STARTER_UTILS_VENDOR_TARGET_ROOT,
|
|
299
|
+
force,
|
|
300
|
+
created,
|
|
301
|
+
overwritten,
|
|
302
|
+
skipped,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
211
306
|
export async function cmdInit(args, { error } = {}) {
|
|
212
307
|
const name = args[0];
|
|
213
308
|
if (!name) {
|
|
@@ -452,3 +547,35 @@ export async function cmdCheck(args, { error } = {}) {
|
|
|
452
547
|
handleProjectAuthoringError(error, err);
|
|
453
548
|
}
|
|
454
549
|
}
|
|
550
|
+
|
|
551
|
+
export async function cmdVendor(args, { error } = {}) {
|
|
552
|
+
try {
|
|
553
|
+
const parsed = parseVendorArgs(args);
|
|
554
|
+
if (parsed.target !== 'helpers') {
|
|
555
|
+
raiseCliError(error, `Unsupported vendor target "${parsed.target}". Usage: ${VENDOR_USAGE}`);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const result = vendorStarterUtils({
|
|
560
|
+
cwd: process.cwd(),
|
|
561
|
+
force: parsed.force,
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
if (parsed.json) {
|
|
565
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
console.log('');
|
|
570
|
+
console.log(' Vendored helper lane');
|
|
571
|
+
console.log('');
|
|
572
|
+
console.log(` Reason: ${result.reasonCode}`);
|
|
573
|
+
console.log(` Target: ${result.targetRoot}`);
|
|
574
|
+
console.log(` Created: ${result.created.length}`);
|
|
575
|
+
console.log(` Overwritten: ${result.overwritten.length}`);
|
|
576
|
+
console.log(` Skipped: ${result.skipped.length}`);
|
|
577
|
+
console.log('');
|
|
578
|
+
} catch (err) {
|
|
579
|
+
handleProjectAuthoringError(error, err);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
@@ -2760,9 +2760,8 @@ export const APP_AND_UI_RUNTIME_CONFORMANCE_CASES = [
|
|
|
2760
2760
|
},
|
|
2761
2761
|
],
|
|
2762
2762
|
nativeFrames: 5,
|
|
2763
|
-
source: () =>
|
|
2763
|
+
source: () => '',
|
|
2764
2764
|
nativeSource: () => `
|
|
2765
|
-
${readConformanceSource('examples/scene-flow-frontier/src/main.js')}
|
|
2766
2765
|
|
|
2767
2766
|
const __checks = [];
|
|
2768
2767
|
let __reported = false;
|
|
@@ -1078,8 +1078,8 @@ export const CORE_RUNTIME_CONFORMANCE_CASES = [
|
|
|
1078
1078
|
},
|
|
1079
1079
|
{
|
|
1080
1080
|
id: 'debug.inspector.stats-shape',
|
|
1081
|
-
expression: "(() => { try { const enabled = aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats(); const disabled = aura.debug.enableInspector(false); const phase2 = stats.phase2 || {}; const rows = [phase2.animation, phase2.tilemap, phase2.scene3d, phase2.particles]; const phase2Ok = rows.every((row) => row && Number.isFinite(row.active) && Number.isFinite(row.total) && Number.isFinite(row.callbackQueueDepth) && row.active >= 0 && row.total >= 0 && row.callbackQueueDepth >= 0); const scene3dRuntime = stats.scene3dRuntime || {}; const submission = scene3dRuntime.submission || {}; const camera = scene3dRuntime.camera || {}; const resources = scene3dRuntime.resources || {}; const cameraVectorsOk = Number.isFinite(camera.position?.x) && Number.isFinite(camera.position?.y) && Number.isFinite(camera.position?.z) && Number.isFinite(camera.target?.x) && Number.isFinite(camera.target?.y) && Number.isFinite(camera.target?.z); const billboardOk = Number.isFinite(submission.billboardCommandsPending) && Number.isFinite(submission.billboardUniqueTextureHandles) && Number.isFinite(submission.billboardLastCommandCount) && Number.isFinite(submission.billboardLastRenderedCount) && Number.isFinite(submission.billboardLastBatchCount) && typeof submission.billboardLastReasonCode === 'string'; const morphOk = Number.isFinite(submission.morphCandidateDrawCount) && Number.isFinite(submission.morphCustomPipelineDrawCount) && Number.isFinite(submission.morphMissingBufferDrawCount) && Number.isFinite(submission.morphPreparedBindGroupCount) && Number.isFinite(submission.morphExecutedBindGroupCount) && Number.isFinite(submission.morphExecutedMeshCount) && Number.isFinite(submission.morphExecutedNonZeroWeightDrawCount) && Number.isFinite(submission.morphExecutedNonZeroWeightMeshCount) && typeof submission.morphLastReasonCode === 'string' && Number.isFinite(resources.morphTrackedMeshCount) && Number.isFinite(resources.morphPendingUploadCount); const scene3dRuntimeOk = Number.isFinite(submission.drawMeshPending) && Number.isFinite(submission.uniqueMeshHandles) && Number.isFinite(submission.uniqueMaterialHandles) && Number.isFinite(submission.nonDefaultTransforms) && billboardOk && morphOk && typeof submission.skyboxRequested === 'boolean' && typeof submission.clearRequested === 'boolean' && typeof camera.mode === 'string' && camera.mode.length > 0 && Number.isFinite(camera.aspect) && Number.isFinite(camera.fovDegrees) && Number.isFinite(camera.near) && Number.isFinite(camera.far) && cameraVectorsOk && Number.isFinite(resources.meshHandlesRegistered) && Number.isFinite(resources.meshUploadsPending) && Number.isFinite(resources.materialHandlesKnown) && Number.isFinite(resources.materialCommandsPending) && Number.isFinite(resources.lightPointCount) && typeof resources.lightDirectionalActive === 'boolean'; return enabled === true && disabled === false && Number.isFinite(stats.frameCount) && Number.isFinite(stats.frame.fps) && Number.isFinite(stats.frame.deltaSeconds) && Number.isFinite(stats.frame.elapsedSeconds) && Number.isFinite(stats.window.width) && Number.isFinite(stats.window.height) && Number.isFinite(stats.window.pixelRatio) && Number.isFinite(stats.queues.draw2dPending) && Number.isFinite(stats.queues.draw3dPending) && Number.isFinite(stats.queues.debugOverlayPending) && phase2Ok && scene3dRuntimeOk; } catch (_) { return false; } })()",
|
|
1082
|
-
debugExpression: "(() => { try { const enabled = aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats(); const disabled = aura.debug.enableInspector(false); const phase2 = stats.phase2 || {}; const rows = [phase2.animation, phase2.tilemap, phase2.scene3d, phase2.particles]; const phase2Rows = rows.map((row) => ({ present: !!row, active: row?.active, total: row?.total, callbackQueueDepth: row?.callbackQueueDepth })); const phase2Ok = rows.every((row) => row && Number.isFinite(row.active) && Number.isFinite(row.total) && Number.isFinite(row.callbackQueueDepth) && row.active >= 0 && row.total >= 0 && row.callbackQueueDepth >= 0); const scene3dRuntime = stats.scene3dRuntime || {}; const submission = scene3dRuntime.submission || {}; const camera = scene3dRuntime.camera || {}; const resources = scene3dRuntime.resources || {}; const cameraVectorsOk = Number.isFinite(camera.position?.x) && Number.isFinite(camera.position?.y) && Number.isFinite(camera.position?.z) && Number.isFinite(camera.target?.x) && Number.isFinite(camera.target?.y) && Number.isFinite(camera.target?.z); const billboardOk = Number.isFinite(submission.billboardCommandsPending) && Number.isFinite(submission.billboardUniqueTextureHandles) && Number.isFinite(submission.billboardLastCommandCount) && Number.isFinite(submission.billboardLastRenderedCount) && Number.isFinite(submission.billboardLastBatchCount) && typeof submission.billboardLastReasonCode === 'string'; const morphOk = Number.isFinite(submission.morphCandidateDrawCount) && Number.isFinite(submission.morphCustomPipelineDrawCount) && Number.isFinite(submission.morphMissingBufferDrawCount) && Number.isFinite(submission.morphPreparedBindGroupCount) && Number.isFinite(submission.morphExecutedBindGroupCount) && Number.isFinite(submission.morphExecutedMeshCount) && Number.isFinite(submission.morphExecutedNonZeroWeightDrawCount) && Number.isFinite(submission.morphExecutedNonZeroWeightMeshCount) && typeof submission.morphLastReasonCode === 'string' && Number.isFinite(resources.morphTrackedMeshCount) && Number.isFinite(resources.morphPendingUploadCount); const scene3dRuntimeOk = Number.isFinite(submission.drawMeshPending) && Number.isFinite(submission.uniqueMeshHandles) && Number.isFinite(submission.uniqueMaterialHandles) && Number.isFinite(submission.nonDefaultTransforms) && billboardOk && morphOk && typeof submission.skyboxRequested === 'boolean' && typeof submission.clearRequested === 'boolean' && typeof submission.environmentMapConfigured === 'boolean' && Number.isFinite(submission.pointShadowLightCount) && Number.isFinite(submission.spotShadowLightCount) && Number.isFinite(submission.pointShadowPassCount) && Number.isFinite(submission.spotShadowPassCount) && typeof camera.mode === 'string' && camera.mode.length > 0 && Number.isFinite(camera.aspect) && Number.isFinite(camera.fovDegrees) && Number.isFinite(camera.near) && Number.isFinite(camera.far) && cameraVectorsOk && Number.isFinite(resources.meshHandlesRegistered) && Number.isFinite(resources.meshUploadsPending) && Number.isFinite(resources.materialHandlesKnown) && Number.isFinite(resources.materialCommandsPending) && Number.isFinite(resources.lightPointCount) && Number.isFinite(resources.lightSpotCount) && typeof resources.lightDirectionalActive === 'boolean'; return { enabled, disabled, frameCount: stats?.frameCount, frame: stats?.frame || null, window: stats?.window || null, queues: stats?.queues || null, phase2Ok, phase2Rows, scene3dRuntimeOk, cameraMode: camera?.mode, cameraAspect: camera?.aspect, cameraVectorsOk, submission, resources }; } catch (error) { return { traceError: String(error && error.message ? error.message : error) }; } })()",
|
|
1081
|
+
expression: "(() => { try { const enabled = aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats(); const disabled = aura.debug.enableInspector(false); const phase2 = stats.phase2 || {}; const rows = [phase2.animation, phase2.tilemap, phase2.scene3d, phase2.particles]; const phase2Ok = rows.every((row) => row && Number.isFinite(row.active) && Number.isFinite(row.total) && Number.isFinite(row.callbackQueueDepth) && row.active >= 0 && row.total >= 0 && row.callbackQueueDepth >= 0); const draw2dRuntime = stats.draw2dRuntime || {}; const fx = draw2dRuntime.fx || {}; const masking = draw2dRuntime.masking || {}; const compositor = draw2dRuntime.compositor || {}; const draw2dRuntimeOk = Number.isFinite(fx.pendingFxCommandCount) && Number.isFinite(fx.lastSubmittedFxCommandCount) && Number.isFinite(fx.lastExecutedFxCommandCount) && typeof fx.lastReasonCode === 'string' && typeof fx.lastOk === 'boolean' && Number.isFinite(masking.pendingPassCount) && Number.isFinite(masking.pendingAdvancedPassCount) && Number.isFinite(masking.lastSubmittedPassCount) && Number.isFinite(masking.lastExecutedPassCount) && Number.isFinite(masking.lastSubmittedCommandCount) && typeof masking.lastReasonCode === 'string' && typeof masking.lastOk === 'boolean' && typeof masking.lastRequestedMaskKind === 'string' && typeof masking.lastRequestedMaskShape === 'string' && Number.isFinite(masking.lastRequestedMaskFeather) && Number.isFinite(compositor.knownGraphCount) && Number.isFinite(compositor.knownStageCount) && typeof compositor.lastGraphName === 'string' && Number.isFinite(compositor.lastGraphStageCount) && Number.isFinite(compositor.lastGraphCommandCount) && typeof compositor.lastGraphReasonCode === 'string' && typeof compositor.lastGraphOk === 'boolean' && Number.isFinite(compositor.pendingExportCount) && Number.isFinite(compositor.lastSubmittedExportCount) && Number.isFinite(compositor.lastExecutedExportCount) && typeof compositor.lastExportReasonCode === 'string' && typeof compositor.lastExportOk === 'boolean'; const scene3dRuntime = stats.scene3dRuntime || {}; const submission = scene3dRuntime.submission || {}; const camera = scene3dRuntime.camera || {}; const resources = scene3dRuntime.resources || {}; const cameraVectorsOk = Number.isFinite(camera.position?.x) && Number.isFinite(camera.position?.y) && Number.isFinite(camera.position?.z) && Number.isFinite(camera.target?.x) && Number.isFinite(camera.target?.y) && Number.isFinite(camera.target?.z); const billboardOk = Number.isFinite(submission.billboardCommandsPending) && Number.isFinite(submission.billboardUniqueTextureHandles) && Number.isFinite(submission.billboardLastCommandCount) && Number.isFinite(submission.billboardLastRenderedCount) && Number.isFinite(submission.billboardLastBatchCount) && typeof submission.billboardLastReasonCode === 'string'; const morphOk = Number.isFinite(submission.morphCandidateDrawCount) && Number.isFinite(submission.morphCustomPipelineDrawCount) && Number.isFinite(submission.morphMissingBufferDrawCount) && Number.isFinite(submission.morphPreparedBindGroupCount) && Number.isFinite(submission.morphExecutedBindGroupCount) && Number.isFinite(submission.morphExecutedMeshCount) && Number.isFinite(submission.morphExecutedNonZeroWeightDrawCount) && Number.isFinite(submission.morphExecutedNonZeroWeightMeshCount) && typeof submission.morphLastReasonCode === 'string' && Number.isFinite(resources.morphTrackedMeshCount) && Number.isFinite(resources.morphPendingUploadCount); const scene3dRuntimeOk = Number.isFinite(submission.drawMeshPending) && Number.isFinite(submission.uniqueMeshHandles) && Number.isFinite(submission.uniqueMaterialHandles) && Number.isFinite(submission.nonDefaultTransforms) && billboardOk && morphOk && typeof submission.skyboxRequested === 'boolean' && typeof submission.clearRequested === 'boolean' && typeof camera.mode === 'string' && camera.mode.length > 0 && Number.isFinite(camera.aspect) && Number.isFinite(camera.fovDegrees) && Number.isFinite(camera.near) && Number.isFinite(camera.far) && cameraVectorsOk && Number.isFinite(resources.meshHandlesRegistered) && Number.isFinite(resources.meshUploadsPending) && Number.isFinite(resources.materialHandlesKnown) && Number.isFinite(resources.materialCommandsPending) && Number.isFinite(resources.lightPointCount) && typeof resources.lightDirectionalActive === 'boolean'; return enabled === true && disabled === false && Number.isFinite(stats.frameCount) && Number.isFinite(stats.frame.fps) && Number.isFinite(stats.frame.deltaSeconds) && Number.isFinite(stats.frame.elapsedSeconds) && Number.isFinite(stats.window.width) && Number.isFinite(stats.window.height) && Number.isFinite(stats.window.pixelRatio) && Number.isFinite(stats.queues.draw2dPending) && Number.isFinite(stats.queues.draw3dPending) && Number.isFinite(stats.queues.debugOverlayPending) && phase2Ok && draw2dRuntimeOk && scene3dRuntimeOk; } catch (_) { return false; } })()",
|
|
1082
|
+
debugExpression: "(() => { try { const enabled = aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats(); const disabled = aura.debug.enableInspector(false); const phase2 = stats.phase2 || {}; const rows = [phase2.animation, phase2.tilemap, phase2.scene3d, phase2.particles]; const phase2Rows = rows.map((row) => ({ present: !!row, active: row?.active, total: row?.total, callbackQueueDepth: row?.callbackQueueDepth })); const phase2Ok = rows.every((row) => row && Number.isFinite(row.active) && Number.isFinite(row.total) && Number.isFinite(row.callbackQueueDepth) && row.active >= 0 && row.total >= 0 && row.callbackQueueDepth >= 0); const draw2dRuntime = stats.draw2dRuntime || {}; const fx = draw2dRuntime.fx || {}; const masking = draw2dRuntime.masking || {}; const compositor = draw2dRuntime.compositor || {}; const draw2dRuntimeOk = Number.isFinite(fx.pendingFxCommandCount) && Number.isFinite(fx.lastSubmittedFxCommandCount) && Number.isFinite(fx.lastExecutedFxCommandCount) && typeof fx.lastReasonCode === 'string' && typeof fx.lastOk === 'boolean' && Number.isFinite(masking.pendingPassCount) && Number.isFinite(masking.pendingAdvancedPassCount) && Number.isFinite(masking.lastSubmittedPassCount) && Number.isFinite(masking.lastExecutedPassCount) && Number.isFinite(masking.lastSubmittedCommandCount) && typeof masking.lastReasonCode === 'string' && typeof masking.lastOk === 'boolean' && typeof masking.lastRequestedMaskKind === 'string' && typeof masking.lastRequestedMaskShape === 'string' && Number.isFinite(masking.lastRequestedMaskFeather) && Number.isFinite(compositor.knownGraphCount) && Number.isFinite(compositor.knownStageCount) && typeof compositor.lastGraphName === 'string' && Number.isFinite(compositor.lastGraphStageCount) && Number.isFinite(compositor.lastGraphCommandCount) && typeof compositor.lastGraphReasonCode === 'string' && typeof compositor.lastGraphOk === 'boolean' && Number.isFinite(compositor.pendingExportCount) && Number.isFinite(compositor.lastSubmittedExportCount) && Number.isFinite(compositor.lastExecutedExportCount) && typeof compositor.lastExportReasonCode === 'string' && typeof compositor.lastExportOk === 'boolean'; const scene3dRuntime = stats.scene3dRuntime || {}; const submission = scene3dRuntime.submission || {}; const camera = scene3dRuntime.camera || {}; const resources = scene3dRuntime.resources || {}; const cameraVectorsOk = Number.isFinite(camera.position?.x) && Number.isFinite(camera.position?.y) && Number.isFinite(camera.position?.z) && Number.isFinite(camera.target?.x) && Number.isFinite(camera.target?.y) && Number.isFinite(camera.target?.z); const billboardOk = Number.isFinite(submission.billboardCommandsPending) && Number.isFinite(submission.billboardUniqueTextureHandles) && Number.isFinite(submission.billboardLastCommandCount) && Number.isFinite(submission.billboardLastRenderedCount) && Number.isFinite(submission.billboardLastBatchCount) && typeof submission.billboardLastReasonCode === 'string'; const morphOk = Number.isFinite(submission.morphCandidateDrawCount) && Number.isFinite(submission.morphCustomPipelineDrawCount) && Number.isFinite(submission.morphMissingBufferDrawCount) && Number.isFinite(submission.morphPreparedBindGroupCount) && Number.isFinite(submission.morphExecutedBindGroupCount) && Number.isFinite(submission.morphExecutedMeshCount) && Number.isFinite(submission.morphExecutedNonZeroWeightDrawCount) && Number.isFinite(submission.morphExecutedNonZeroWeightMeshCount) && typeof submission.morphLastReasonCode === 'string' && Number.isFinite(resources.morphTrackedMeshCount) && Number.isFinite(resources.morphPendingUploadCount); const scene3dRuntimeOk = Number.isFinite(submission.drawMeshPending) && Number.isFinite(submission.uniqueMeshHandles) && Number.isFinite(submission.uniqueMaterialHandles) && Number.isFinite(submission.nonDefaultTransforms) && billboardOk && morphOk && typeof submission.skyboxRequested === 'boolean' && typeof submission.clearRequested === 'boolean' && typeof submission.environmentMapConfigured === 'boolean' && Number.isFinite(submission.pointShadowLightCount) && Number.isFinite(submission.spotShadowLightCount) && Number.isFinite(submission.pointShadowPassCount) && Number.isFinite(submission.spotShadowPassCount) && typeof camera.mode === 'string' && camera.mode.length > 0 && Number.isFinite(camera.aspect) && Number.isFinite(camera.fovDegrees) && Number.isFinite(camera.near) && Number.isFinite(camera.far) && cameraVectorsOk && Number.isFinite(resources.meshHandlesRegistered) && Number.isFinite(resources.meshUploadsPending) && Number.isFinite(resources.materialHandlesKnown) && Number.isFinite(resources.materialCommandsPending) && Number.isFinite(resources.lightPointCount) && Number.isFinite(resources.lightSpotCount) && typeof resources.lightDirectionalActive === 'boolean'; return { enabled, disabled, frameCount: stats?.frameCount, frame: stats?.frame || null, window: stats?.window || null, queues: stats?.queues || null, phase2Ok, phase2Rows, draw2dRuntimeOk, draw2dRuntime, scene3dRuntimeOk, cameraMode: camera?.mode, cameraAspect: camera?.aspect, cameraVectorsOk, submission, resources }; } catch (error) { return { traceError: String(error && error.message ? error.message : error) }; } })()",
|
|
1083
1083
|
},
|
|
1084
1084
|
{
|
|
1085
1085
|
id: 'debug.inspector.scene3d-animation-shape',
|
|
@@ -1093,6 +1093,10 @@ export const CORE_RUNTIME_CONFORMANCE_CASES = [
|
|
|
1093
1093
|
id: 'optional.modules.steam.not-exposed',
|
|
1094
1094
|
expression: "typeof aura.steam === 'undefined' && !Object.prototype.hasOwnProperty.call(aura, 'steam')",
|
|
1095
1095
|
},
|
|
1096
|
+
{
|
|
1097
|
+
id: 'providers.steam.not-exposed-by-default',
|
|
1098
|
+
expression: "typeof aura.providers === 'undefined' || typeof aura.providers.steam === 'undefined'",
|
|
1099
|
+
},
|
|
1096
1100
|
],
|
|
1097
1101
|
nativeFrames: 2,
|
|
1098
1102
|
source: `
|
|
@@ -1377,6 +1377,204 @@ export const SCENE3D_AND_MEDIA_CONFORMANCE_CASES = [
|
|
|
1377
1377
|
`,
|
|
1378
1378
|
nativeFrames: 2,
|
|
1379
1379
|
},
|
|
1380
|
+
{
|
|
1381
|
+
id: 'threejs-material-runtime-parity-native',
|
|
1382
|
+
modes: ['native'],
|
|
1383
|
+
namespaces: ['draw3d', 'camera3d', 'debug', 'material', 'mesh'],
|
|
1384
|
+
functions: [
|
|
1385
|
+
'aura.draw3d.clear3d',
|
|
1386
|
+
'aura.draw3d.drawMesh',
|
|
1387
|
+
'aura.camera3d.perspective',
|
|
1388
|
+
'aura.camera3d.setPosition',
|
|
1389
|
+
'aura.camera3d.lookAt',
|
|
1390
|
+
'aura.debug.inspectorStats',
|
|
1391
|
+
'aura.material.create',
|
|
1392
|
+
'aura.material.createDataTexture',
|
|
1393
|
+
'aura.material.setTexture',
|
|
1394
|
+
'aura.material.setTextureTransform',
|
|
1395
|
+
'aura.material.setAlphaCutoff',
|
|
1396
|
+
'aura.material.setDoubleSided',
|
|
1397
|
+
'aura.material.setSheen',
|
|
1398
|
+
'aura.material.setSpecularFactor',
|
|
1399
|
+
'aura.material.unload',
|
|
1400
|
+
'aura.mesh.createBox',
|
|
1401
|
+
'aura.mesh.unload',
|
|
1402
|
+
],
|
|
1403
|
+
nativeChecks: [
|
|
1404
|
+
{
|
|
1405
|
+
id: 'material.runtime-parity.surface.methods',
|
|
1406
|
+
expression: "(() => ['clear3d','drawMesh'].every((name) => typeof aura.draw3d?.[name] === 'function') && ['perspective','setPosition','lookAt'].every((name) => typeof aura.camera3d?.[name] === 'function') && typeof aura.debug?.inspectorStats === 'function' && ['create','createDataTexture','setTexture','setTextureTransform','setAlphaCutoff','setDoubleSided','setSheen','setSpecularFactor','unload'].every((name) => typeof aura.material?.[name] === 'function') && ['createBox','unload'].every((name) => typeof aura.mesh?.[name] === 'function'))()",
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
id: 'material.runtime-parity.reason-codes.stable',
|
|
1410
|
+
expression: "(() => { const reasonOf = (entry) => entry && (entry.reasonCode || entry.reason) || null; const material = aura.material.create({ color: { r: 0.4, g: 0.5, b: 0.6, a: 1 }, alphaMode: 'mask' }); const invalidHandle = aura.material.setAlphaCutoff('bad', 0.4); const invalidCutoff = aura.material.setAlphaCutoff(material, 'bad'); const invalidDoubleSided = aura.material.setDoubleSided(material, 'yes'); const invalidSheenRoughness = aura.material.setSheen(material, 'bad', { r: 1, g: 1, b: 1 }); const invalidSheenColor = aura.material.setSheen(material, 0.4, null); const invalidSpecularFactor = aura.material.setSpecularFactor(material, 'high'); let unknownDataTexture = null; try { aura.material.setTexture(material, 999999); unknownDataTexture = 'no_throw'; } catch (error) { unknownDataTexture = String(error && error.message || error); } aura.material.unload(material); return reasonOf(invalidHandle) === 'invalid_material_handle' && reasonOf(invalidCutoff) === 'invalid_alpha_cutoff_value' && reasonOf(invalidDoubleSided) === 'invalid_double_sided_value' && reasonOf(invalidSheenRoughness) === 'invalid_sheen_roughness_value' && reasonOf(invalidSheenColor) === 'invalid_sheen_color' && reasonOf(invalidSpecularFactor) === 'invalid_specular_factor_value' && String(unknownDataTexture || '').includes('unknown data texture handle'); })()",
|
|
1411
|
+
},
|
|
1412
|
+
{
|
|
1413
|
+
id: 'material.runtime-parity.setup',
|
|
1414
|
+
expression: `(() => { try { aura.debug.enableInspector(true); const mesh = aura.mesh.createBox(1, 1, 1); const material = aura.material.create({ color: { r: 0.55, g: 0.62, b: 0.78, a: 1 }, metallic: 0.08, roughness: 0.84, alphaMode: 'mask', alphaCutoff: 0.2, doubleSided: false, sheenColor: { r: 0.12, g: 0.14, b: 0.16 }, sheenRoughness: 0.08, specularFactor: 0.25 }); const pixels = new Uint8Array([24, 48, 96, 255, 64, 92, 132, 255, 128, 168, 212, 255, 80, 120, 176, 255]); const dataTexture = aura.material.createDataTexture(2, 2, pixels, { format: 'rgba8', filter: 'linear', wrap: 'repeat' }); const before = aura.debug.inspectorStats() || {}; const setTexture = aura.material.setTexture(material, dataTexture); const setTextureTransform = aura.material.setTextureTransform(material, { repeat: { x: 2, y: 2 }, offset: { x: 0.25, y: 0.125 }, rotation: 0.1, center: { x: 0.5, y: 0.5 } }); const setCutoff = aura.material.setAlphaCutoff(material, 2); const setDouble = aura.material.setDoubleSided(material, true); const setSheen = aura.material.setSheen(material, 2, { r: 0.84, g: 0.63, b: 0.41 }); const setSpecular = aura.material.setSpecularFactor(material, -1); const after = aura.debug.inspectorStats() || {}; aura.camera3d.perspective(58, 0.1, 40); aura.camera3d.setPosition(0, 1.4, 4.2); aura.camera3d.lookAt(0, 0.2, 0); const baseDraw = aura.draw; aura.draw = function () { aura.draw3d.clear3d({ r: 0.018, g: 0.02, b: 0.03, a: 1 }); aura.draw3d.drawMesh(mesh, material, { position: { x: 0, y: 0.1, z: 0 } }); if (typeof baseDraw === 'function') baseDraw(); }; globalThis.__materialRuntimeParityProbe = { mesh, material, dataTexture, beforeResources: before?.scene3dRuntime?.resources || {}, afterResources: after?.scene3dRuntime?.resources || {}, setTexture, setTextureTransform, setCutoff, setDouble, setSheen, setSpecular }; return Number.isInteger(mesh) && mesh > 0 && Number.isInteger(material) && material > 0 && Number.isInteger(dataTexture) && dataTexture > 0 && (setTexture === undefined || setTexture?.ok !== false) && (setTextureTransform === undefined || setTextureTransform?.ok !== false) && (setCutoff === undefined || setCutoff?.ok !== false) && (setDouble === undefined || setDouble?.ok !== false) && (setSheen === undefined || setSheen?.ok !== false) && (setSpecular === undefined || setSpecular?.ok !== false) && Number((after?.scene3dRuntime?.resources?.materialUpdatesPending || 0) - (before?.scene3dRuntime?.resources?.materialUpdatesPending || 0)) === 6; } catch (_) { return false; } })()`,
|
|
1415
|
+
debugExpression: `(() => { try { const probe = globalThis.__materialRuntimeParityProbe || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1416
|
+
},
|
|
1417
|
+
],
|
|
1418
|
+
nativePostChecks: [
|
|
1419
|
+
{
|
|
1420
|
+
id: 'material.runtime-parity.evidence',
|
|
1421
|
+
expression: `(() => { try { const probe = globalThis.__materialRuntimeParityProbe || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); const resources = stats?.scene3dRuntime?.resources || {}; const submission = stats?.scene3dRuntime?.submission || {}; const beforeUpdates = Number(probe?.beforeResources?.materialUpdatesPending || 0); const afterUpdates = Number(probe?.afterResources?.materialUpdatesPending || 0); return Number.isInteger(probe.mesh) && probe.mesh > 0 && Number.isInteger(probe.material) && probe.material > 0 && Number.isInteger(probe.dataTexture) && probe.dataTexture > 0 && (afterUpdates - beforeUpdates) === 6 && Number(resources.materialUpdatesPending || 0) === 0 && Number(resources.materialCommandsPending || 0) === 0 && Number(resources.materialHandlesKnown || 0) >= 2 && Number(submission.drawMeshPending || 0) >= 1; } catch (_) { return false; } })()`,
|
|
1422
|
+
debugExpression: `(() => { try { const probe = globalThis.__materialRuntimeParityProbe || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1423
|
+
},
|
|
1424
|
+
],
|
|
1425
|
+
source: `
|
|
1426
|
+
globalThis.__materialRuntimeParityProbe = null;
|
|
1427
|
+
`,
|
|
1428
|
+
nativeFrames: 2,
|
|
1429
|
+
},
|
|
1430
|
+
{
|
|
1431
|
+
id: 'threejs-particles3d-lifecycle-postfx-runtime',
|
|
1432
|
+
modes: ['native'],
|
|
1433
|
+
namespaces: ['particles3d', 'draw3d', 'camera3d', 'debug', 'material'],
|
|
1434
|
+
functions: [
|
|
1435
|
+
'aura.particles3d.create',
|
|
1436
|
+
'aura.particles3d.destroy',
|
|
1437
|
+
'aura.particles3d.emit',
|
|
1438
|
+
'aura.particles3d.burst',
|
|
1439
|
+
'aura.particles3d.pause',
|
|
1440
|
+
'aura.particles3d.resume',
|
|
1441
|
+
'aura.particles3d.stop',
|
|
1442
|
+
'aura.particles3d.update',
|
|
1443
|
+
'aura.particles3d.draw',
|
|
1444
|
+
'aura.particles3d.getState',
|
|
1445
|
+
'aura.draw3d.clear3d',
|
|
1446
|
+
'aura.draw3d.createRenderTarget',
|
|
1447
|
+
'aura.draw3d.setRenderTarget',
|
|
1448
|
+
'aura.draw3d.destroyRenderTarget',
|
|
1449
|
+
'aura.draw3d.setPostFXPass',
|
|
1450
|
+
'aura.draw3d.removePostFXPass',
|
|
1451
|
+
'aura.draw3d.getPostFXState',
|
|
1452
|
+
'aura.camera3d.perspective',
|
|
1453
|
+
'aura.camera3d.setPosition',
|
|
1454
|
+
'aura.camera3d.lookAt',
|
|
1455
|
+
'aura.debug.enableInspector',
|
|
1456
|
+
'aura.debug.inspectorStats',
|
|
1457
|
+
'aura.material.create',
|
|
1458
|
+
'aura.material.createDataTexture',
|
|
1459
|
+
'aura.material.setTexture',
|
|
1460
|
+
],
|
|
1461
|
+
nativeChecks: [
|
|
1462
|
+
{
|
|
1463
|
+
id: 'particles3d.runtime.surface.methods',
|
|
1464
|
+
expression: "(() => ['create','destroy','emit','burst','pause','resume','stop','update','draw','getState'].every((name) => typeof aura.particles3d?.[name] === 'function') && ['clear3d','createRenderTarget','setRenderTarget','destroyRenderTarget','setPostFXPass','removePostFXPass','getPostFXState'].every((name) => typeof aura.draw3d?.[name] === 'function') && ['perspective','setPosition','lookAt'].every((name) => typeof aura.camera3d?.[name] === 'function') && typeof aura.debug?.inspectorStats === 'function' && ['create','createDataTexture','setTexture'].every((name) => typeof aura.material?.[name] === 'function'))()",
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
id: 'particles3d.runtime.lifecycle-and-postfx.setup',
|
|
1468
|
+
expression: `(() => { try { aura.draw3d.setRenderTarget(null); aura.draw3d.removePostFXPass('colorGrade'); aura.camera3d.perspective(55, 0.1, 40); aura.camera3d.setPosition(0, 1.4, 4.5); aura.camera3d.lookAt(0, 0.35, 0); const renderTarget = aura.draw3d.createRenderTarget(96, 54, { depth: true }); const created = aura.particles3d.create({ emitRate: 0, emitBurst: 1, lifetime: [2, 2], velocity: { x: 0, y: 1, z: 0 }, acceleration: { x: 0, y: 0, z: 0 }, size: [0.18, 0.18], color: [1, 0.6, 0.2, 0.78], blendMode: 'alpha' }); const emitterId = created.emitterId; const emitted = aura.particles3d.emit(emitterId, 2); const paused = aura.particles3d.pause(emitterId); aura.particles3d.update(0.35); const pausedState = aura.particles3d.getState(emitterId); const resumedBeforeStop = aura.particles3d.resume(emitterId); const stopped = aura.particles3d.stop(emitterId); aura.particles3d.update(0.35); const stoppedState = aura.particles3d.getState(emitterId); const resumed = aura.particles3d.resume(emitterId); aura.particles3d.setEmitRate(emitterId, 2); const oneShot = aura.particles3d.burst({ position: { x: 0.55, y: 0.35, z: 0 }, count: 2, lifetime: [0.5, 0.5], velocity: { x: 0, y: 1, z: 0 }, acceleration: { x: 0, y: 0, z: 0 }, size: 0.12, color: [0.2, 0.9, 1, 0.7], blendMode: 'alpha' }); const postfx = aura.draw3d.setPostFXPass('colorGrade', { strength: 0.25, customParams: { brightness: 0.98, contrast: 1.04, saturation: 1.02, gamma: 1.0 } }); const baseDraw = aura.draw; globalThis.__particles3dLifecyclePostfx = { emitterId, emitted, paused, pausedState, resumedBeforeStop, stopped, stoppedState, resumed, oneShot, renderTarget, frames: [] }; aura.draw = function () { const probe = globalThis.__particles3dLifecyclePostfx || {}; const frameIndex = Array.isArray(probe.frames) ? probe.frames.length : 0; const captureToRenderTarget = frameIndex < 2; if (captureToRenderTarget) { aura.draw3d.setRenderTarget(probe.renderTarget, { position: { x: 2.8, y: 1.9, z: 2.7 }, target: { x: 0.1, y: 0.35, z: 0 }, fovDegrees: 48, near: 0.1, far: 24 }); } else { aura.draw3d.setRenderTarget(null); } aura.draw3d.clear3d({ r: 0.018, g: 0.02, b: 0.028, a: 1 }); aura.particles3d.update(0.25); const drawResult = aura.particles3d.draw(); aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); const particles = stats?.scene3dRuntime?.particles3d || {}; const submission = stats?.scene3dRuntime?.submission || {}; probe.frames.push({ frameIndex, target: captureToRenderTarget ? 'renderTarget' : 'swapchain', drawOk: drawResult?.ok === true, drawReason: drawResult?.reasonCode || drawResult?.reason || null, drawCount: Number(drawResult?.drawn || 0), particleCount: Number(particles.particleCount || 0), particleDrawCalls: Number(particles.drawCalls || 0), billboardPending: Number(submission.billboardCommandsPending || 0), observedPostfxReason: String(submission.postfxLastExecutionReasonCode || ''), observedPostfxExecutedPassCount: Number(submission.postfxLastExecutedPassCount || 0) }); if (typeof baseDraw === 'function') baseDraw(); }; return Number.isInteger(renderTarget) && renderTarget > 0 && Number.isInteger(emitterId) && emitterId > 0 && emitted?.ok === true && emitted?.spawned === 2 && paused?.ok === true && pausedState?.paused === true && pausedState?.particles === 3 && resumedBeforeStop?.ok === true && stopped?.ok === true && stoppedState?.stopped === true && stoppedState?.particles === 3 && resumed?.ok === true && oneShot?.ok === true && oneShot?.oneShot === true && postfx?.reasonCode === 'postfx_ok'; } catch (_) { return false; } })()`,
|
|
1469
|
+
debugExpression: `(() => { try { const probe = globalThis.__particles3dLifecyclePostfx || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null, postfx: aura.draw3d.getPostFXState() || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1470
|
+
},
|
|
1471
|
+
],
|
|
1472
|
+
nativePostChecks: [
|
|
1473
|
+
{
|
|
1474
|
+
id: 'particles3d.runtime.lifecycle-and-postfx.evidence',
|
|
1475
|
+
expression: `(() => { try { const probe = globalThis.__particles3dLifecyclePostfx || {}; const frames = Array.isArray(probe.frames) ? probe.frames : []; const frame0 = frames[0] || {}; const frame1 = frames[1] || {}; const frame2 = frames[2] || {}; const frame3 = frames[3] || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); const particles = stats?.scene3dRuntime?.particles3d || {}; const submission = stats?.scene3dRuntime?.submission || {}; const emitterState = aura.particles3d.getState(probe.emitterId); const oneShotState = aura.particles3d.getState(probe.oneShot?.emitterId || 0); aura.draw3d.setRenderTarget(null); aura.draw3d.removePostFXPass('colorGrade'); const destroyedRenderTarget = aura.draw3d.destroyRenderTarget(probe.renderTarget); const missingRenderTargetDestroy = aura.draw3d.destroyRenderTarget(probe.renderTarget); const destroyedOneShot = probe.oneShot?.emitterId ? aura.particles3d.destroy(probe.oneShot.emitterId) : null; const destroyedEmitter = aura.particles3d.destroy(probe.emitterId); return Number.isInteger(probe.renderTarget) && probe.renderTarget > 0 && Number.isInteger(probe.emitterId) && probe.emitterId > 0 && probe.emitted?.spawned === 2 && probe.pausedState?.paused === true && probe.pausedState?.emitting === false && probe.stoppedState?.stopped === true && probe.stoppedState?.emitting === false && frames.length === 4 && frames.every((frame, index) => frame.frameIndex === index && frame.drawOk === true && frame.drawReason === 'particles3d_draw_submitted' && frame.drawCount > 0 && frame.particleCount > 0 && frame.particleDrawCalls === frame.drawCount && frame.billboardPending >= frame.drawCount) && frame0.target === 'renderTarget' && frame1.target === 'renderTarget' && frame2.target === 'swapchain' && frame3.target === 'swapchain' && frame1.observedPostfxReason === 'postfx_skipped_render_target' && frame2.observedPostfxReason === 'postfx_skipped_render_target' && frame3.observedPostfxReason === 'postfx_executed' && frame3.observedPostfxExecutedPassCount === 1 && Number(particles.particleCount || 0) > 0 && Number(particles.drawCalls || 0) > 0 && Number(particles.updateFingerprint || 0) > 0 && Number(particles.orderFingerprint || 0) > 0 && Number(particles.updatedEmitters || 0) >= 1 && Number(submission.billboardLastCommandCount || 0) > 0 && Number(submission.billboardLastRenderedCount || 0) > 0 && String(submission.billboardLastReasonCode || '') === 'billboard_submitted' && Number(submission.postfxPassCount || 0) === 1 && Number(submission.postfxEnabledPassCount || 0) === 1 && Number(submission.postfxLastExecutedPassCount || 0) === 1 && String(submission.postfxLastExecutionReasonCode || '') === 'postfx_executed' && submission.postfxLastExecutionOk === true && emitterState?.paused === false && emitterState?.stopped === false && emitterState?.emitting === true && oneShotState === null && destroyedRenderTarget === true && missingRenderTargetDestroy === false && destroyedEmitter?.ok === true && Number(destroyedEmitter?.particlesCleared || -1) >= 0 && (destroyedOneShot === null || destroyedOneShot?.reason === 'missing_emitter'); } catch (_) { return false; } })()`,
|
|
1476
|
+
debugExpression: `(() => { try { const probe = globalThis.__particles3dLifecyclePostfx || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null, postfx: aura.draw3d.getPostFXState() || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1477
|
+
},
|
|
1478
|
+
],
|
|
1479
|
+
source: `
|
|
1480
|
+
globalThis.__particles3dLifecyclePostfx = { frames: [] };
|
|
1481
|
+
`,
|
|
1482
|
+
nativeFrames: 4,
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
id: 'threejs-procedural-surface-authoring-native',
|
|
1486
|
+
modes: ['native'],
|
|
1487
|
+
namespaces: ['draw3d', 'camera3d', 'debug', 'material', 'mesh'],
|
|
1488
|
+
functions: [
|
|
1489
|
+
'aura.draw3d.clear3d',
|
|
1490
|
+
'aura.draw3d.drawMesh',
|
|
1491
|
+
'aura.draw3d.billboard',
|
|
1492
|
+
'aura.draw3d.addDecal',
|
|
1493
|
+
'aura.camera3d.perspective',
|
|
1494
|
+
'aura.camera3d.setPosition',
|
|
1495
|
+
'aura.camera3d.lookAt',
|
|
1496
|
+
'aura.debug.inspectorStats',
|
|
1497
|
+
'aura.material.create',
|
|
1498
|
+
'aura.material.createDataTexture',
|
|
1499
|
+
'aura.material.setTexture',
|
|
1500
|
+
'aura.material.setTextureTransform',
|
|
1501
|
+
'aura.mesh.createBox',
|
|
1502
|
+
'aura.mesh.unload',
|
|
1503
|
+
],
|
|
1504
|
+
nativeChecks: [
|
|
1505
|
+
{
|
|
1506
|
+
id: 'procedural.surface-authoring.surface.methods',
|
|
1507
|
+
expression: "(() => ['clear3d','drawMesh','billboard','addDecal'].every((name) => typeof aura.draw3d?.[name] === 'function') && ['perspective','setPosition','lookAt'].every((name) => typeof aura.camera3d?.[name] === 'function') && typeof aura.debug?.inspectorStats === 'function' && ['create','createDataTexture','setTexture','setTextureTransform'].every((name) => typeof aura.material?.[name] === 'function') && ['createBox','unload'].every((name) => typeof aura.mesh?.[name] === 'function'))()",
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
id: 'procedural.surface-authoring.runtime.setup',
|
|
1511
|
+
expression: `(() => { try { const makeTexture = (rgba) => { const pixels = new Uint8Array(4 * 4 * 4); for (let index = 0; index < 16; index += 1) { const offset = index * 4; pixels[offset + 0] = rgba[0]; pixels[offset + 1] = rgba[1]; pixels[offset + 2] = rgba[2]; pixels[offset + 3] = rgba[3]; } return aura.material.createDataTexture(4, 4, pixels, { format: 'rgba8', filter: 'linear', wrap: 'repeat' }); }; const floorMesh = aura.mesh.createBox(8, 0.2, 8); const coverMesh = aura.mesh.createBox(0.8, 2.0, 0.8); const floorMaterial = aura.material.create({ color: { r: 0.24, g: 0.28, b: 0.34, a: 1 }, roughness: 0.9, metallic: 0.04 }); const coverMaterial = aura.material.create({ color: { r: 0.42, g: 0.38, b: 0.34, a: 1 }, roughness: 0.84, metallic: 0.05 }); const billboardTexture = makeTexture([36, 180, 224, 216]); const decalTexture = makeTexture([42, 220, 250, 196]); aura.material.setTexture(floorMaterial, billboardTexture); aura.material.setTextureTransform(floorMaterial, { repeat: { x: 3, y: 3 }, offset: { x: 0.125, y: 0.25 } }); aura.camera3d.perspective(58, 0.1, 60); aura.camera3d.setPosition(0, 2.4, 5.8); aura.camera3d.lookAt(0, 0.45, 0); const baseDraw = aura.draw; globalThis.__proceduralSurfaceAuthoring = { floorMesh, coverMesh, floorMaterial, coverMaterial, billboardTexture, decalTexture, frames: [], authoringContract: null }; aura.draw = function () { const probe = globalThis.__proceduralSurfaceAuthoring || {}; const frameIndex = Array.isArray(probe.frames) ? probe.frames.length : 0; const readSubmission = () => { aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return stats?.scene3dRuntime?.submission || {}; }; const drawBridgeBillboards = () => { aura.draw3d.billboard({ dataTextureHandle: probe.billboardTexture }, { x: -1.1, y: 0.1, z: 0.15, width: 1.15, height: 1.75, mode: 'face' }); aura.draw3d.billboard({ dataTextureHandle: probe.billboardTexture }, { x: 1.0, y: 0.0, z: -0.15, width: 1.2, height: 1.2, mode: 'axis', color: { r: 1, g: 0.9, b: 0.82, a: 0.88 } }); }; const drawProceduralDecals = () => { aura.draw3d.addDecal({ position: { x: 0.5, y: -0.98, z: 0.3 }, rotation: { x: -Math.PI * 0.5, y: 0, z: 0 }, size: { x: 2.2, y: 2.2, z: 1.2 }, textureHandle: probe.decalTexture, color: { r: 0.3, g: 0.92, b: 1.0, a: 0.84 }, opacity: 0.72, roughness: 0.2 }); aura.draw3d.addDecal({ position: { x: -0.75, y: -0.99, z: -0.4 }, rotation: { x: -Math.PI * 0.5, y: 0, z: 0 }, size: { x: 1.5, y: 1.5, z: 0.8 }, color: { r: 1.0, g: 0.56, b: 0.18, a: 0.64 }, opacity: 0.58, roughness: 0.12 }); }; aura.camera3d.setPosition(Math.sin(frameIndex * 0.3) * 0.8, 2.4, 5.8 - frameIndex * 0.1); aura.camera3d.lookAt(0, 0.45, 0); aura.draw3d.clear3d({ r: 0.02, g: 0.024, b: 0.034, a: 1 }); aura.draw3d.drawMesh(probe.floorMesh, probe.floorMaterial, { position: { x: 0, y: -1.1, z: 0 } }); aura.draw3d.drawMesh(probe.coverMesh, probe.coverMaterial, { position: { x: 0.8, y: -0.05, z: 0.9 } }); let authoringContract = probe.authoringContract || null; if (frameIndex === 0) { const billboardBefore = readSubmission(); aura.draw3d.billboard({}, { x: 0, y: 0, z: 0, width: 1, height: 1, mode: 'face' }); aura.draw3d.billboard({ dataTextureHandle: 0 }, { x: 0, y: 0, z: 0, width: 1, height: 1, mode: 'axis' }); const billboardAfterInvalid = readSubmission(); drawBridgeBillboards(); const billboardAfterValid = readSubmission(); const decalBefore = readSubmission(); aura.draw3d.addDecal({ position: { x: 0.15, y: -0.98, z: 0.05 }, size: { x: 1.2, y: 1.2, z: 0.6 }, texture: 'fx/decal.png', textureHandle: probe.decalTexture }); const decalAfterAmbiguous = readSubmission(); aura.draw3d.addDecal({ position: { x: 0.15, y: -0.98, z: 0.05 }, size: { x: 1.2, y: 1.2, z: 0.6 } }); const decalAfterMissing = readSubmission(); aura.draw3d.addDecal({ position: { x: 0.15, y: -0.98, z: 0.05 }, size: { x: 1.2, y: 1.2, z: 0.6 }, color: { r: 'bad', g: 0, b: 0, a: 1 } }); const decalAfterBadColor = readSubmission(); drawProceduralDecals(); const decalAfterValid = readSubmission(); authoringContract = { invalidBillboardPendingDelta: Number(billboardAfterInvalid.billboardCommandsPending || 0) - Number(billboardBefore.billboardCommandsPending || 0), acceptedBillboardPendingDelta: Number(billboardAfterValid.billboardCommandsPending || 0) - Number(billboardAfterInvalid.billboardCommandsPending || 0), invalidDecalPendingDelta: Number(decalAfterBadColor.decalCommandsPending || 0) - Number(decalBefore.decalCommandsPending || 0), acceptedDecalPendingDelta: Number(decalAfterValid.decalCommandsPending || 0) - Number(decalAfterBadColor.decalCommandsPending || 0), invalidDecalReasonTrace: [String(decalAfterAmbiguous.decalLastReasonCode || ''), String(decalAfterMissing.decalLastReasonCode || ''), String(decalAfterBadColor.decalLastReasonCode || '')].join('|') }; probe.authoringContract = authoringContract; } else { drawBridgeBillboards(); drawProceduralDecals(); } probe.frames.push({ frameIndex, billboards: 2, decals: 2, decalModes: 'textureHandle|color', bridgePendingDelta: frameIndex === 0 ? Number(authoringContract?.acceptedBillboardPendingDelta || 0) : null, invalidBillboardPendingDelta: frameIndex === 0 ? Number(authoringContract?.invalidBillboardPendingDelta || 0) : null, invalidDecalReasonTrace: frameIndex === 0 ? String(authoringContract?.invalidDecalReasonTrace || '') : null }); if (typeof baseDraw === 'function') baseDraw(); }; return Number.isInteger(floorMesh) && floorMesh > 0 && Number.isInteger(coverMesh) && coverMesh > 0 && Number.isInteger(floorMaterial) && floorMaterial > 0 && Number.isInteger(coverMaterial) && coverMaterial > 0 && Number.isInteger(billboardTexture) && billboardTexture > 0 && Number.isInteger(decalTexture) && decalTexture > 0; } catch (_) { return false; } })()`,
|
|
1512
|
+
debugExpression: `(() => { try { const probe = globalThis.__proceduralSurfaceAuthoring || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1513
|
+
},
|
|
1514
|
+
],
|
|
1515
|
+
nativePostChecks: [
|
|
1516
|
+
{
|
|
1517
|
+
id: 'procedural.surface-authoring.runtime.evidence',
|
|
1518
|
+
expression: `(() => { try { const probe = globalThis.__proceduralSurfaceAuthoring || {}; const frames = Array.isArray(probe.frames) ? probe.frames : []; const authoringContract = probe.authoringContract || {}; const frame0 = frames[0] || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); const scene3d = stats.scene3dRuntime || {}; const submission = scene3d.submission || {}; const resources = scene3d.resources || {}; return Number.isInteger(probe.floorMesh) && probe.floorMesh > 0 && Number.isInteger(probe.coverMesh) && probe.coverMesh > 0 && Number.isInteger(probe.floorMaterial) && probe.floorMaterial > 0 && Number.isInteger(probe.coverMaterial) && probe.coverMaterial > 0 && Number.isInteger(probe.billboardTexture) && probe.billboardTexture > 0 && Number.isInteger(probe.decalTexture) && probe.decalTexture > 0 && frames.length === 4 && frames.every((frame, index) => frame.frameIndex === index && frame.billboards === 2 && frame.decals === 2 && frame.decalModes === 'textureHandle|color') && frame0.bridgePendingDelta === 2 && frame0.invalidBillboardPendingDelta === 0 && frame0.invalidDecalReasonTrace === 'decal_invalid_texture|decal_invalid_texture|decal_invalid_color' && Number(authoringContract.invalidBillboardPendingDelta || -1) === 0 && Number(authoringContract.acceptedBillboardPendingDelta || 0) === 2 && Number(authoringContract.invalidDecalPendingDelta || -1) === 0 && Number(authoringContract.acceptedDecalPendingDelta || 0) === 2 && String(authoringContract.invalidDecalReasonTrace || '') === 'decal_invalid_texture|decal_invalid_texture|decal_invalid_color' && Number(resources.materialHandlesKnown || 0) >= 3 && Number(submission.drawMeshPending || 0) >= 2 && Number(submission.billboardCommandsPending || 0) >= 2 && Number(submission.billboardUniqueTextureHandles || 0) === 1 && Number(submission.billboardLastCommandCount || 0) === 2 && Number(submission.billboardLastRenderedCount || 0) === 2 && Number(submission.billboardLastBatchCount || 0) === 1 && String(submission.billboardLastReasonCode || '') === 'billboard_submitted' && Number(submission.decalCommandsPending || 0) >= 2 && Number(submission.decalLastCommandCount || 0) === 2 && Number(submission.decalLastRenderedCount || 0) === 2 && Number(submission.decalLastBatchCount || 0) >= 1 && Number(submission.decalLastSkippedDegenerateCount || 0) === 0 && Number(submission.decalLastSkippedMissingTextureCount || 0) === 0 && Number(submission.decalLastSkippedTransparentCount || 0) === 0 && String(submission.decalLastReasonCode || '') === 'decal_submitted' && Number(submission.decalLastOrderFingerprint || 0) > 0; } catch (_) { return false; } })()`,
|
|
1519
|
+
debugExpression: `(() => { try { const probe = globalThis.__proceduralSurfaceAuthoring || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1520
|
+
},
|
|
1521
|
+
],
|
|
1522
|
+
source: `
|
|
1523
|
+
globalThis.__proceduralSurfaceAuthoring = { frames: [] };
|
|
1524
|
+
`,
|
|
1525
|
+
nativeFrames: 4,
|
|
1526
|
+
},
|
|
1527
|
+
{
|
|
1528
|
+
id: 'threejs-renderer-breadth-proof-native',
|
|
1529
|
+
modes: ['native'],
|
|
1530
|
+
namespaces: ['draw3d', 'camera3d', 'collision3d', 'debug', 'material', 'mesh', 'scene3d'],
|
|
1531
|
+
functions: [
|
|
1532
|
+
'aura.draw3d.clear3d',
|
|
1533
|
+
'aura.draw3d.drawMesh',
|
|
1534
|
+
'aura.draw3d.addDecal',
|
|
1535
|
+
'aura.draw3d.createRenderTarget',
|
|
1536
|
+
'aura.draw3d.setRenderTarget',
|
|
1537
|
+
'aura.draw3d.destroyRenderTarget',
|
|
1538
|
+
'aura.draw3d.setPostFXPass',
|
|
1539
|
+
'aura.draw3d.removePostFXPass',
|
|
1540
|
+
'aura.draw3d.getPostFXState',
|
|
1541
|
+
'aura.camera3d.perspective',
|
|
1542
|
+
'aura.camera3d.setPosition',
|
|
1543
|
+
'aura.camera3d.lookAt',
|
|
1544
|
+
'aura.collision3d.closestPoint',
|
|
1545
|
+
'aura.collision3d.sphereCast',
|
|
1546
|
+
'aura.debug.inspectorStats',
|
|
1547
|
+
'aura.material.create',
|
|
1548
|
+
'aura.material.setRenderTargetTexture',
|
|
1549
|
+
'aura.material.unload',
|
|
1550
|
+
'aura.mesh.createBox',
|
|
1551
|
+
'aura.mesh.createSphere',
|
|
1552
|
+
'aura.mesh.unload',
|
|
1553
|
+
'aura.scene3d.getRenderSubmissionState',
|
|
1554
|
+
],
|
|
1555
|
+
nativeChecks: [
|
|
1556
|
+
{
|
|
1557
|
+
id: 'renderer.breadth-proof.surface.methods',
|
|
1558
|
+
expression: "(() => ['clear3d','drawMesh','addDecal','createRenderTarget','setRenderTarget','destroyRenderTarget','setPostFXPass','removePostFXPass','getPostFXState'].every((name) => typeof aura.draw3d?.[name] === 'function') && ['perspective','setPosition','lookAt'].every((name) => typeof aura.camera3d?.[name] === 'function') && ['closestPoint','sphereCast'].every((name) => typeof aura.collision3d?.[name] === 'function') && typeof aura.debug?.inspectorStats === 'function' && ['create','setRenderTargetTexture','unload'].every((name) => typeof aura.material?.[name] === 'function') && ['createBox','createSphere','unload'].every((name) => typeof aura.mesh?.[name] === 'function') && typeof aura.scene3d?.getRenderSubmissionState === 'function')()",
|
|
1559
|
+
},
|
|
1560
|
+
{
|
|
1561
|
+
id: 'renderer.breadth-proof.runtime.setup',
|
|
1562
|
+
expression: `(() => { try { const floorMesh = aura.mesh.createBox(6, 0.2, 6); const obstacleMesh = aura.mesh.createBox(1.2, 1.8, 1.2); const monitorMesh = aura.mesh.createBox(2.2, 1.4, 0.12); const orbMesh = aura.mesh.createSphere(1, 12); const floorMaterial = aura.material.create({ color: { r: 0.08, g: 0.09, b: 0.11, a: 1 }, roughness: 0.9, metallic: 0.05 }); const obstacleMaterial = aura.material.create({ color: { r: 0.16, g: 0.18, b: 0.22, a: 1 }, roughness: 0.82, metallic: 0.08 }); const monitorMaterial = aura.material.create({ color: { r: 1, g: 1, b: 1, a: 1 }, roughness: 0.16, metallic: 0.0 }); const orbMaterial = aura.material.create({ color: { r: 1.0, g: 0.42, b: 0.16, a: 1 }, roughness: 0.12, metallic: 0.0 }); aura.draw3d.removePostFXPass('colorGrade'); aura.draw3d.removePostFXPass('bloom'); aura.draw3d.removePostFXPass('heatDistortion'); const rt = aura.draw3d.createRenderTarget(96, 54, { depth: true }); aura.material.setRenderTargetTexture(monitorMaterial, rt); const colorGrade = aura.draw3d.setPostFXPass('colorGrade', { strength: 0.62, customParams: { brightness: 0.98, contrast: 1.08, saturation: 1.08, gamma: 1.0 } }); const bloom = aura.draw3d.setPostFXPass('bloom', { strength: 1.08, radius: 0.86, threshold: 0.58 }); const heat = aura.draw3d.setPostFXPass('heatDistortion', { strength: 0.18, radius: 0.5, threshold: 0.62, customParams: { distortion_scale: 1.0, band_frequency: 18.0, drift_speed: 0.92, depth_weight: 0.34, turbulence: 0.42 } }); aura.camera3d.perspective(56, 0.1, 48); aura.camera3d.setPosition(5.6, 3.1, 5.2); aura.camera3d.lookAt(0, -0.15, 0); const baseDraw = aura.draw; const drawWorld = (probe, includeMonitor) => { aura.draw3d.drawMesh(floorMesh, floorMaterial, { position: { x: 0, y: -1.05, z: 0 } }); aura.draw3d.drawMesh(obstacleMesh, obstacleMaterial, { position: { x: 0, y: -0.1, z: 0 } }); aura.draw3d.drawMesh(obstacleMesh, obstacleMaterial, { position: { x: 0, y: 0.65, z: -2.3 }, scale: { x: 4.5, y: 2.4, z: 0.1 } }); aura.draw3d.drawMesh(orbMesh, orbMaterial, { position: { x: probe.point.x, y: probe.point.y + 0.08, z: probe.point.z }, scale: { x: 0.18 + (probe.alert * 0.22), y: 0.18 + (probe.alert * 0.22), z: 0.18 + (probe.alert * 0.22) } }); if (includeMonitor) { aura.draw3d.drawMesh(monitorMesh, monitorMaterial, { position: { x: 2.1, y: 0.1, z: -2.04 } }); } }; globalThis.__rendererBreadthProof = { rt, floorMesh, obstacleMesh, monitorMesh, orbMesh, floorMaterial, obstacleMaterial, monitorMaterial, orbMaterial, frames: [], setupReasons: [colorGrade?.reasonCode || null, bloom?.reasonCode || null, heat?.reasonCode || null] }; aura.draw = function () { const probeState = globalThis.__rendererBreadthProof || {}; const frameIndex = Array.isArray(probeState.frames) ? probeState.frames.length : 0; const start = { x: -2.4 + (frameIndex * 0.2), y: -0.1, z: 0 }; const end = { x: 2.0, y: -0.1, z: 0 }; const obstacle = { x: 0, y: -0.1, z: 0, w: 1.2, h: 1.8, d: 1.2 }; const hit = aura.collision3d.sphereCast(start, end, 0.24, obstacle); const closest = aura.collision3d.closestPoint(obstacle, { x: 1.8, y: 1.0, z: 1.6 }) || { x: 0, y: -0.1, z: 0 }; const point = hit && hit.hit ? hit.point : { x: 0.6, y: -0.1, z: 0 }; const normal = hit && hit.hit ? hit.normal : { x: 1, y: 0, z: 0 }; const toi = hit && hit.hit ? Number(hit.toi || 1) : 1; const alert = hit && hit.hit ? Number((1.0 - (toi * 0.55)).toFixed(6)) : 0; aura.draw3d.setPostFXPass('heatDistortion', { strength: 0.12 + (alert * 0.28), radius: 0.5, threshold: 0.62, customParams: { distortion_scale: 0.9 + (alert * 0.9), band_frequency: 18.0, drift_speed: 0.92, depth_weight: 0.34, turbulence: 0.42 + (alert * 0.18) } }); aura.camera3d.setPosition(5.6 - (frameIndex * 0.15), 3.1, 5.2 - (frameIndex * 0.08)); aura.camera3d.lookAt(0, -0.15, 0); aura.draw3d.setRenderTarget(probeState.rt, { position: { x: 3.1, y: 2.3, z: 3.0 }, target: { x: 0, y: -0.1, z: 0 }, fovDegrees: 50, near: 0.1, far: 24 }); aura.draw3d.clear3d({ r: 0.012, g: 0.015, b: 0.022, a: 1 }); drawWorld({ point, alert }, false); aura.draw3d.setRenderTarget(null); aura.draw3d.clear3d({ r: 0.015, g: 0.018, b: 0.026, a: 1 }); drawWorld({ point, alert }, true); aura.draw3d.addDecal({ position: { x: point.x, y: -0.94, z: point.z }, rotation: { x: -Math.PI * 0.5, y: 0, z: 0 }, size: { x: 0.9 + (alert * 0.8), y: 0.9, z: 0.7 + (alert * 0.4) }, color: { r: 1.0, g: 0.42 + (alert * 0.18), b: 0.12, a: 0.82 }, opacity: 0.3 + (alert * 0.34), roughness: 0.18 }); probeState.frames.push({ frameIndex, hit: !!(hit && hit.hit), toi: hit && hit.hit ? Number(Number(hit.toi || 0).toFixed(6)) : null, pointX: Number(Number(point.x || 0).toFixed(6)), pointZ: Number(Number(point.z || 0).toFixed(6)), normalX: hit && hit.hit ? Number(Number(normal.x || 0).toFixed(6)) : null, closestZ: Number(Number(closest.z || 0).toFixed(6)), alert }); if (typeof baseDraw === 'function') baseDraw(); }; const postfx = aura.draw3d.getPostFXState() || {}; return [floorMesh, obstacleMesh, monitorMesh, orbMesh, floorMaterial, obstacleMaterial, monitorMaterial, orbMaterial, rt].every((handle) => Number.isInteger(handle) && handle > 0) && colorGrade?.reasonCode === 'postfx_ok' && bloom?.reasonCode === 'postfx_ok' && heat?.reasonCode === 'postfx_ok' && Array.isArray(postfx?.passes) && postfx.passes.length === 3; } catch (_) { return false; } })()`,
|
|
1563
|
+
debugExpression: `(() => { try { const probe = globalThis.__rendererBreadthProof || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null, render: aura.scene3d.getRenderSubmissionState() || null, postfx: aura.draw3d.getPostFXState() || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1564
|
+
},
|
|
1565
|
+
],
|
|
1566
|
+
nativePostChecks: [
|
|
1567
|
+
{
|
|
1568
|
+
id: 'renderer.breadth-proof.runtime.evidence',
|
|
1569
|
+
expression: `(() => { try { const probe = globalThis.__rendererBreadthProof || {}; const frames = Array.isArray(probe.frames) ? probe.frames : []; const frame0 = frames[0] || {}; const frame3 = frames[3] || {}; const postfx = aura.draw3d.getPostFXState() || {}; const passNames = new Set(Array.isArray(postfx?.passes) ? postfx.passes.map((pass) => pass.pass) : []); aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); const scene3d = stats.scene3dRuntime || {}; const submission = scene3d.submission || {}; const resources = scene3d.resources || {}; const render = aura.scene3d.getRenderSubmissionState() || {}; const destroyed = aura.draw3d.destroyRenderTarget(probe.rt); const missingDestroy = aura.draw3d.destroyRenderTarget(probe.rt); aura.draw3d.removePostFXPass('heatDistortion'); aura.draw3d.removePostFXPass('bloom'); aura.draw3d.removePostFXPass('colorGrade'); aura.material.unload(probe.orbMaterial); aura.material.unload(probe.monitorMaterial); aura.material.unload(probe.obstacleMaterial); aura.material.unload(probe.floorMaterial); aura.mesh.unload(probe.orbMesh); aura.mesh.unload(probe.monitorMesh); aura.mesh.unload(probe.obstacleMesh); aura.mesh.unload(probe.floorMesh); return Number.isInteger(probe.rt) && probe.rt > 0 && Array.isArray(probe.setupReasons) && probe.setupReasons.join('|') === 'postfx_ok|postfx_ok|postfx_ok' && frames.length === 4 && frames.every((frame, index) => frame.frameIndex === index && frame.hit === true && Number.isFinite(frame.toi) && frame.toi > 0 && frame.toi < 1 && Number.isFinite(frame.alert) && frame.alert > 0 && frame.normalX === -1) && frame0.toi > frame3.toi && frame0.pointX === frame3.pointX && frame0.pointZ === frame3.pointZ && frame0.closestZ === frame3.closestZ && Number(postfx?.totalPasses || 0) === 3 && Number(postfx?.enabledPasses || 0) === 3 && passNames.has('colorGrade') && passNames.has('bloom') && passNames.has('heatDistortion') && Number(submission?.scene3dSubmitted || 0) >= 1 && Number(submission?.drawMeshPending || 0) >= 5 && Number(submission?.decalLastCommandCount || 0) === 1 && Number(submission?.decalLastRenderedCount || 0) === 1 && String(submission?.decalLastReasonCode || '') === 'decal_submitted' && Number(submission?.postfxPassCount || 0) === 3 && Number(submission?.postfxEnabledPassCount || 0) === 3 && Number(submission?.postfxLastExecutedPassCount || 0) === 3 && Number(submission?.postfxLastExecutionFingerprint || 0) > 0 && String(submission?.postfxLastExecutionReasonCode || '') === 'postfx_executed' && submission?.postfxLastExecutionOk === true && String(submission?.postfxLastReasonCode || '') === 'postfx_ok' && submission?.postfxLastOk === true && Number(resources?.materialHandlesKnown || 0) >= 4 && Number(render?.submitted || 0) >= 1 && Number(render?.submitted || 0) === Number(submission?.scene3dSubmitted || 0) && Number(render?.orderFingerprint || 0) > 0 && destroyed === true && missingDestroy === false; } catch (_) { return false; } })()`,
|
|
1570
|
+
debugExpression: `(() => { try { const probe = globalThis.__rendererBreadthProof || {}; aura.debug.enableInspector(true); const stats = aura.debug.inspectorStats() || {}; aura.debug.enableInspector(false); return { probe, scene3dRuntime: stats.scene3dRuntime || null, render: aura.scene3d.getRenderSubmissionState() || null, postfx: aura.draw3d.getPostFXState() || null }; } catch (error) { return { debugError: String(error && error.message ? error.message : error) }; } })()`,
|
|
1571
|
+
},
|
|
1572
|
+
],
|
|
1573
|
+
source: `
|
|
1574
|
+
globalThis.__rendererBreadthProof = { frames: [] };
|
|
1575
|
+
`,
|
|
1576
|
+
nativeFrames: 4,
|
|
1577
|
+
},
|
|
1380
1578
|
{
|
|
1381
1579
|
id: 'threejs-occlusion-skinned-runtime',
|
|
1382
1580
|
modes: ['native'],
|
|
@@ -2090,5 +2288,45 @@ export const SCENE3D_AND_MEDIA_CONFORMANCE_CASES = [
|
|
|
2090
2288
|
aura.setup = function () {};
|
|
2091
2289
|
`,
|
|
2092
2290
|
nativeFrames: 2,
|
|
2291
|
+
},
|
|
2292
|
+
{
|
|
2293
|
+
id: 'threejs-stage191-contract-closure-native',
|
|
2294
|
+
modes: ['native'],
|
|
2295
|
+
namespaces: ['draw3d', 'camera3d', 'collision3d', 'scene3d', 'window'],
|
|
2296
|
+
functions: [
|
|
2297
|
+
'aura.draw3d.createCubeCamera',
|
|
2298
|
+
'aura.draw3d.updateCubeCamera',
|
|
2299
|
+
'aura.draw3d.destroyCubeCamera',
|
|
2300
|
+
'aura.draw3d.setEnvironmentMap',
|
|
2301
|
+
'aura.draw3d.setPostFXPass',
|
|
2302
|
+
'aura.draw3d.removePostFXPass',
|
|
2303
|
+
'aura.draw3d.getPostFXState',
|
|
2304
|
+
'aura.camera3d.perspective',
|
|
2305
|
+
'aura.camera3d.setPosition',
|
|
2306
|
+
'aura.camera3d.lookAt',
|
|
2307
|
+
'aura.scene3d.screenToRay',
|
|
2308
|
+
'aura.window.getSize',
|
|
2309
|
+
'aura.collision3d.boxBox',
|
|
2310
|
+
'aura.collision3d.sphereBox',
|
|
2311
|
+
'aura.collision3d.raySphere',
|
|
2312
|
+
'aura.collision3d.rayBox',
|
|
2313
|
+
'aura.collision3d.pointBox',
|
|
2314
|
+
'aura.collision3d.rayPlane',
|
|
2315
|
+
'aura.collision3d.rayTriangle',
|
|
2316
|
+
],
|
|
2317
|
+
nativeChecks: [
|
|
2318
|
+
{
|
|
2319
|
+
id: 'stage191.contract-closure.surface.methods',
|
|
2320
|
+
expression: "(() => ['createCubeCamera','updateCubeCamera','destroyCubeCamera','setEnvironmentMap','setPostFXPass','removePostFXPass','getPostFXState'].every((name) => typeof aura.draw3d?.[name] === 'function') && ['perspective','setPosition','lookAt'].every((name) => typeof aura.camera3d?.[name] === 'function') && typeof aura.scene3d?.screenToRay === 'function' && typeof aura.window?.getSize === 'function' && ['boxBox','sphereBox','raySphere','rayBox','pointBox','rayPlane','rayTriangle'].every((name) => typeof aura.collision3d?.[name] === 'function'))()",
|
|
2321
|
+
},
|
|
2322
|
+
{
|
|
2323
|
+
id: 'stage191.contract-closure.runtime.truth',
|
|
2324
|
+
expression: "(() => { let cubeCamera = null; try { aura.draw3d.removePostFXPass('outline'); aura.draw3d.setEnvironmentMap(null); aura.camera3d.perspective(60, 0.1, 100); aura.camera3d.setPosition(0, 0, 4); aura.camera3d.lookAt(0, 0, 0); const size = aura.window.getSize(); if (!size || size.width <= 0 || size.height <= 0) return false; cubeCamera = aura.draw3d.createCubeCamera({ position: { x: 0, y: 0, z: 0 }, near: 0.25, far: 48, resolution: 128, facesPerFrame: 2 }); aura.draw3d.setEnvironmentMap(cubeCamera); aura.draw3d.updateCubeCamera(cubeCamera); const outline = aura.draw3d.setPostFXPass('outline', { strength: 0.85, radius: 1.2, threshold: 0.12, depthThreshold: 0.015, lumaThreshold: 0.08, outlineR: 0.1, outlineG: 0.9, outlineB: 1.0 }); const state = aura.draw3d.getPostFXState() || {}; const outlinePass = Array.isArray(state?.passes) ? state.passes.find((pass) => pass.pass === 'outline') : null; const center = aura.scene3d.screenToRay(size.width / 2, size.height / 2); const corner = aura.scene3d.screenToRay(0, 0); const invalid = aura.scene3d.screenToRay(NaN, 0); const box = { x: 0, y: 0, z: 0, w: 2, h: 2, d: 2 }; const plane = { x: 0, y: 0, z: 0, nx: 0, ny: 1, nz: 0 }; const ray = { x: 0, y: 0, z: 2, dx: 0, dy: 0, dz: -1, maxDist: 10 }; const v0 = { x: -1, y: -1, z: 0 }; const v1 = { x: 1, y: -1, z: 0 }; const v2 = { x: 0, y: 1, z: 0 }; const triHit = aura.collision3d.rayTriangle(ray, v0, v1, v2); const triMiss = aura.collision3d.rayTriangle({ x: 3, y: 0, z: 2, dx: 0, dy: 0, dz: -1, maxDist: 10 }, v0, v1, v2); return outline?.reasonCode === 'postfx_ok' && cubeCamera?.ok === true && cubeCamera?.type === 'cubeCamera' && Number(cubeCamera?.resolution || 0) === 128 && Number(cubeCamera?.facesPerFrame || 0) === 2 && !!outlinePass && Number(state?.totalPasses || 0) >= 1 && Number(state?.enabledPasses || 0) >= 1 && state?.lastReasonCode === 'postfx_ok' && state?.lastOk === true && center?.ok === true && Math.abs(Number(center?.direction?.x || 0)) < 0.1 && Math.abs(Number(center?.direction?.y || 0)) < 0.1 && Number(center?.direction?.z || 0) < -0.9 && corner?.ok === true && Number(corner?.direction?.x || 0) < 0 && Number(corner?.direction?.y || 0) > 0 && Number(corner?.direction?.z || 0) < 0 && invalid?.ok === false && invalid?.reason === 'invalid_screen_coords' && aura.collision3d.boxBox(box, { x: 1, y: 1, z: 1, w: 2, h: 2, d: 2 }) === true && aura.collision3d.sphereBox({ x: 1, y: 1, z: 1, radius: 0.5 }, box) === true && aura.collision3d.raySphere({ x: -2, y: 1, z: 1, dx: 1, dy: 0, dz: 0, maxDist: 10 }, { x: 1, y: 1, z: 1, radius: 0.5 }) === true && aura.collision3d.rayBox({ x: -2, y: 1, z: 1, dx: 1, dy: 0, dz: 0, maxDist: 10 }, box) === true && aura.collision3d.pointBox({ x: 1, y: 1, z: 1 }, box) === true && aura.collision3d.pointBox({ x: -0.1, y: 0, z: 0 }, box) === false && aura.collision3d.rayPlane({ x: 0, y: 2, z: 0, dx: 0, dy: -1, dz: 0, maxDist: 5 }, plane) === true && triHit && triHit.hit === true && Math.abs(Number(triHit?.point?.z || 0)) < 1e-6 && Math.abs(Math.abs(Number(triHit?.normal?.z || 0)) - 1) < 1e-6 && triMiss === false; } catch (_) { return false; } finally { try { aura.draw3d.removePostFXPass('outline'); aura.draw3d.setEnvironmentMap(null); if (cubeCamera) aura.draw3d.destroyCubeCamera(cubeCamera); } catch (_) {} } })()",
|
|
2325
|
+
},
|
|
2326
|
+
],
|
|
2327
|
+
source: `
|
|
2328
|
+
aura.setup = function () {};
|
|
2329
|
+
`,
|
|
2330
|
+
nativeFrames: 1,
|
|
2093
2331
|
}
|
|
2094
2332
|
];
|