@carbonenginejs/runtime-trinity 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/curves/CjsGrannyCurves.js +12 -13
  2. package/dist/curves/CjsGrannyCurves.js.map +1 -1
  3. package/dist/eve/EveBannerSet.js +20 -1
  4. package/dist/eve/EveBannerSet.js.map +1 -1
  5. package/dist/eve/EveBoosterSet2.js +19 -1
  6. package/dist/eve/EveBoosterSet2.js.map +1 -1
  7. package/dist/eve/EveComponentTypes.js +116 -0
  8. package/dist/eve/EveComponentTypes.js.map +1 -0
  9. package/dist/eve/EveHazeSet.js +18 -1
  10. package/dist/eve/EveHazeSet.js.map +1 -1
  11. package/dist/eve/EvePlaneSet.js +19 -1
  12. package/dist/eve/EvePlaneSet.js.map +1 -1
  13. package/dist/eve/EveSpotlightSet.js +18 -1
  14. package/dist/eve/EveSpotlightSet.js.map +1 -1
  15. package/dist/eve/EveSpriteLineSet.js +18 -1
  16. package/dist/eve/EveSpriteLineSet.js.map +1 -1
  17. package/dist/eve/EveSpriteSet.js +18 -1
  18. package/dist/eve/EveSpriteSet.js.map +1 -1
  19. package/dist/eve/EveUpdateContext.js +195 -31
  20. package/dist/eve/EveUpdateContext.js.map +1 -1
  21. package/dist/eve/attachment/turrets/EveTurretFiringFX.js +23 -1
  22. package/dist/eve/attachment/turrets/EveTurretFiringFX.js.map +1 -1
  23. package/dist/eve/attachment/turrets/EveTurretSet.js +43 -1
  24. package/dist/eve/attachment/turrets/EveTurretSet.js.map +1 -1
  25. package/dist/eve/child/EveChildContainer.js +95 -60
  26. package/dist/eve/child/EveChildContainer.js.map +1 -1
  27. package/dist/eve/child/EveChildFogVolume.js +14 -1
  28. package/dist/eve/child/EveChildFogVolume.js.map +1 -1
  29. package/dist/eve/child/EveChildInstancedMeshes.js +43 -1
  30. package/dist/eve/child/EveChildInstancedMeshes.js.map +1 -1
  31. package/dist/eve/child/EveChildLightingOverride.js +14 -1
  32. package/dist/eve/child/EveChildLightingOverride.js.map +1 -1
  33. package/dist/eve/child/EveChildMesh.js +121 -80
  34. package/dist/eve/child/EveChildMesh.js.map +1 -1
  35. package/dist/eve/child/EveChildTransform.js +27 -17
  36. package/dist/eve/child/EveChildTransform.js.map +1 -1
  37. package/dist/eve/index.js +2 -0
  38. package/dist/eve/index.js.map +1 -1
  39. package/dist/eve/renderable/stretch/EveFiringEffectElementContainer.js +14 -1
  40. package/dist/eve/renderable/stretch/EveFiringEffectElementContainer.js.map +1 -1
  41. package/dist/eve/renderable/stretch/EveStretch.js +11 -1
  42. package/dist/eve/renderable/stretch/EveStretch.js.map +1 -1
  43. package/dist/eve/renderable/stretch/EveStretch2.js +14 -1
  44. package/dist/eve/renderable/stretch/EveStretch2.js.map +1 -1
  45. package/dist/eve/renderable/stretch/EveStretch3.js +24 -1
  46. package/dist/eve/renderable/stretch/EveStretch3.js.map +1 -1
  47. package/dist/eve/scene/EveSpaceScene.js +443 -16
  48. package/dist/eve/scene/EveSpaceScene.js.map +1 -1
  49. package/dist/eve/spaceObject/EveEffectRoot2.js +28 -1
  50. package/dist/eve/spaceObject/EveEffectRoot2.js.map +1 -1
  51. package/dist/eve/spaceObject/EveMobile.js +25 -1
  52. package/dist/eve/spaceObject/EveMobile.js.map +1 -1
  53. package/dist/eve/spaceObject/EveSpaceObject2.js +59 -1
  54. package/dist/eve/spaceObject/EveSpaceObject2.js.map +1 -1
  55. package/dist/generated/eve/child/EveChildCloud2.js +88 -5
  56. package/dist/generated/eve/child/EveChildCloud2.js.map +1 -1
  57. package/dist/generated/eve/child/EveChildExplosion.js +17 -1
  58. package/dist/generated/eve/child/EveChildExplosion.js.map +1 -1
  59. package/dist/generated/eve/child/EveChildInstanceContainer.js +29 -1
  60. package/dist/generated/eve/child/EveChildInstanceContainer.js.map +1 -1
  61. package/dist/generated/eve/child/EveChildParticleSystem.js +32 -24
  62. package/dist/generated/eve/child/EveChildParticleSystem.js.map +1 -1
  63. package/dist/generated/eve/child/EveChildPlug.js +23 -1
  64. package/dist/generated/eve/child/EveChildPlug.js.map +1 -1
  65. package/dist/generated/eve/child/EveChildPostProcessVolume.js +27 -14
  66. package/dist/generated/eve/child/EveChildPostProcessVolume.js.map +1 -1
  67. package/dist/generated/eve/child/EveChildRef.js +17 -1
  68. package/dist/generated/eve/child/EveChildRef.js.map +1 -1
  69. package/dist/generated/eve/child/EveChildSocket.js +17 -1
  70. package/dist/generated/eve/child/EveChildSocket.js.map +1 -1
  71. package/dist/generated/eve/child/behaviors/BehaviorGroup.js +43 -40
  72. package/dist/generated/eve/child/behaviors/BehaviorGroup.js.map +1 -1
  73. package/dist/generated/eve/child/procedural/EveChildProceduralContainer.js +53 -49
  74. package/dist/generated/eve/child/procedural/EveChildProceduralContainer.js.map +1 -1
  75. package/dist/generated/eve/scene/EveComponentRegistry.js +11 -0
  76. package/dist/generated/eve/scene/EveComponentRegistry.js.map +1 -1
  77. package/dist/generated/eve/scene/TriShadowFrustum.js +74 -22
  78. package/dist/generated/eve/scene/TriShadowFrustum.js.map +1 -1
  79. package/dist/generated/eve/scene/TriShadowOrthoFrustum.js +128 -26
  80. package/dist/generated/eve/scene/TriShadowOrthoFrustum.js.map +1 -1
  81. package/dist/generated/eve/smartLights/EveChildSmartLightSet.js +37 -24
  82. package/dist/generated/eve/smartLights/EveChildSmartLightSet.js.map +1 -1
  83. package/dist/generated/eve/smartLights/EveSmartLightPointLight.js +29 -28
  84. package/dist/generated/eve/smartLights/EveSmartLightPointLight.js.map +1 -1
  85. package/dist/generated/eve/spaceObject/EveShip2.js +39 -19
  86. package/dist/generated/eve/spaceObject/EveShip2.js.map +1 -1
  87. package/dist/generated/eve/spaceObject/swarm/EveSwarm.js +28 -1
  88. package/dist/generated/eve/spaceObject/swarm/EveSwarm.js.map +1 -1
  89. package/dist/generated/eve/spaceObject/swarm/EveSwarmRenderable.js +28 -1
  90. package/dist/generated/eve/spaceObject/swarm/EveSwarmRenderable.js.map +1 -1
  91. package/dist/index.js +3 -0
  92. package/dist/index.js.map +1 -1
  93. package/dist/trinityCore/TriFrustum.js +374 -0
  94. package/dist/trinityCore/TriFrustum.js.map +1 -0
  95. package/dist/trinityCore/TriFrustumOrtho.js +158 -0
  96. package/dist/trinityCore/TriFrustumOrtho.js.map +1 -0
  97. package/dist/trinityCore/index.js +2 -0
  98. package/dist/trinityCore/index.js.map +1 -1
  99. package/package.json +2 -2
@@ -1,18 +1,77 @@
1
1
  import { identity as _identity, applyDecs2311 as _applyDecs2311 } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
2
  import { io, type, carbon, impl, schema } from '@carbonenginejs/core-types/schema';
3
3
  import { CjsModel } from '@carbonenginejs/core-types/model';
4
+ import { mat4 } from '@carbonenginejs/core-math/mat4';
4
5
  import { quat } from '@carbonenginejs/core-math/quat';
5
6
  import { vec3 } from '@carbonenginejs/core-math/vec3';
6
7
  import { vec4 } from '@carbonenginejs/core-math/vec4';
7
8
  import { EveEntity as _EveEntity } from '../../generated/eve/EveEntity.js';
8
9
  import { EveComponentRegistry as _EveComponentRegistry } from '../../generated/eve/scene/EveComponentRegistry.js';
10
+ import { Tr2PostProcess2 as _Tr2PostProcess } from '../../postProcess/Tr2PostProcess2.js';
11
+ import { Tr2PostProcessAttributes as _Tr2PostProcessAttrib } from '../../postProcess/Tr2PostProcessAttributes.js';
12
+ import { EveComponentType } from '../EveComponentTypes.js';
9
13
  import { EveUpdateContext as _EveUpdateContext } from '../EveUpdateContext.js';
14
+ import { EveEffectRoot2 as _EveEffectRoot } from '../spaceObject/EveEffectRoot2.js';
10
15
 
11
16
  let _initProto, _initClass, _init_visualizeMethod, _init_extra_visualizeMethod, _init_envMap1ResPath, _init_extra_envMap1ResPath, _init_envMap2ResPath, _init_extra_envMap2ResPath, _init_envMap3ResPath, _init_extra_envMap3ResPath, _init_lowQualityNebulaResPath, _init_extra_lowQualityNebulaResPath, _init_lowQualityNebulaMixResPath, _init_extra_lowQualityNebulaMixResPath, _init_envMapResPath, _init_extra_envMapResPath, _init_fogColor, _init_extra_fogColor, _init_sunDirection, _init_extra_sunDirection, _init_ambientColor, _init_extra_ambientColor, _init_shLightingManager, _init_extra_shLightingManager, _init_combinedPostProcessAttributes, _init_extra_combinedPostProcessAttributes, _init_dataTextureMgr, _init_extra_dataTextureMgr, _init_dynamicObjectReflectionEnabled, _init_extra_dynamicObjectReflectionEnabled, _init_componentRegistry, _init_extra_componentRegistry, _init_cameraAttachmentParent, _init_extra_cameraAttachmentParent, _init_postProcessDebug, _init_extra_postProcessDebug, _init_curveSets, _init_extra_curveSets, _init_defaultDiffuseRoughness, _init_extra_defaultDiffuseRoughness, _init_fogStart, _init_extra_fogStart, _init_fogEnd, _init_extra_fogEnd, _init_reflectionIntensity, _init_extra_reflectionIntensity, _init_distanceFields, _init_extra_distanceFields, _init_backgroundEffect, _init_extra_backgroundEffect, _init_backgroundReflectionIntensity, _init_extra_backgroundReflectionIntensity, _init_nebulaIntensity, _init_extra_nebulaIntensity, _init_display, _init_extra_display, _init_backgroundRenderingEnabled, _init_extra_backgroundRenderingEnabled, _init_update, _init_extra_update, _init_impostorManager, _init_extra_impostorManager, _init_lensflares, _init_extra_lensflares, _init_externalParameters, _init_extra_externalParameters, _init_fogMax, _init_extra_fogMax, _init_staticParticles, _init_extra_staticParticles, _init_debugRenderer, _init_extra_debugRenderer, _init_objects, _init_extra_objects, _init_uiObjects, _init_extra_uiObjects, _init_backgroundObjects, _init_extra_backgroundObjects, _init_planets, _init_extra_planets, _init_raytracingManager, _init_extra_raytracingManager, _init_reflectionBackLightingColor, _init_extra_reflectionBackLightingColor, _init_reflectionBackLightingContrast, _init_extra_reflectionBackLightingContrast, _init_reflectionProbe, _init_extra_reflectionProbe, _init_volumetricsRenderer, _init_extra_volumetricsRenderer, _init_starfield, _init_extra_starfield, _init_planetScale, _init_extra_planetScale, _init_planetCameraScale, _init_extra_planetCameraScale, _init_subSurfaceScattering, _init_extra_subSurfaceScattering, _init_shadowQualitySetting, _init_extra_shadowQualitySetting, _init_sunDiffuseColor, _init_extra_sunDiffuseColor, _init_sunDiffuseColorWithDynamicLights, _init_extra_sunDiffuseColorWithDynamicLights, _init_envMapRotation, _init_extra_envMapRotation, _init_ballpark, _init_extra_ballpark, _init_name, _init_extra_name, _init_sunBall, _init_extra_sunBall, _init_postprocess, _init_extra_postprocess, _init_virtualCameraSystem, _init_extra_virtualCameraSystem, _init_warpTunnel, _init_extra_warpTunnel, _init_perFrameDebug, _init_extra_perFrameDebug, _init_cascadedShadowMap, _init_extra_cascadedShadowMap, _init_updateTime, _init_extra_updateTime, _init_useSunDiffuseColorWithDynamicLights, _init_extra_useSunDiffuseColorWithDynamicLights, _init_envMap, _init_extra_envMap, _init_envMap2, _init_extra_envMap2, _init_envMap3, _init_extra_envMap3;
12
17
 
13
18
  // Module scratch for the per-frame sun-direction read (assume-dirty).
14
19
  const sunDirectionScratch = vec3.create();
15
20
 
21
+ // The scene-root parent transform for the visibility pass (Carbon
22
+ // EveSpaceScene.cpp:1441 `const Matrix& identity = IdentityMatrix()`). Module
23
+ // const, NEVER mutated - objects in m_objects are scene roots.
24
+ const IDENTITY = mat4.create();
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // DRIVER-ORDER CONTRACT (per frame) - the CPU visibility/gather drive.
28
+ // Carbon runs steps 5-12 inside EveSpaceScene::BeginRender/GatherBatches
29
+ // (EveSpaceScene.cpp:1295-1427/1433-1525); CarbonEngineJS splits them into
30
+ // scene-owned methods that an engine driver calls in this exact order:
31
+ //
32
+ // 1. Host stamps `updateContext.renderContext` (view -> derived inverse-view
33
+ // + viewPos) and `updateContext.device`.
34
+ // 2. Driver derives the frustum:
35
+ // `frustum.DeriveFrustum(view, viewPos, projection, viewport)` from that
36
+ // same renderContext state (Carbon cpp:476).
37
+ // 3. `scene.StampFrameContext({ frustum, thresholds..., lodFactor,
38
+ // raytracingEnabled })`.
39
+ // 4. `scene.Update(realTime, simTime)` - internally ends with
40
+ // `UpdatePostProcessAttributes()` then the sun-direction read (Carbon
41
+ // cpp:584 -> 589).
42
+ // 5. `scene.BlendLightingOverrides()` - BeginRender phase, before any gather
43
+ // (Carbon cpp:1333, before GatherBatches cpp:1387).
44
+ // 6. (engine) volumetrics `UpdateFogSettings(scene.componentRegistry,
45
+ // scene.updateContext)` - engine reads "FroxelFogSettings"; not scene
46
+ // work (cpp:1365-1370).
47
+ // 7. `scene.UpdateVisibility(updateContext.renderContext
48
+ // .GetInverseViewTransform())` - the cpp:1443-1467 block.
49
+ // 8. `const renderables = scene.GetRenderables([])` - pre-culled
50
+ // (cpp:1470-1507 minus impostors).
51
+ // 9. `batchManager.Collect(renderables, reason, updateContext.renderContext)`
52
+ // - with engine-registered collectors covering Carbon's [QUADS]
53
+ // (cpp:1509-1511) and [INSTANCED] (cpp:1516-1520; the instanced collector
54
+ // reads "InstancedMeshProvider" from `scene.componentRegistry`);
55
+ // `Finalize` inside Collect = Carbon FinalizeBatches cpp:1522.
56
+ // 10. `scene.GatherLights(lightManager)` - AFTER step 9 (Carbon cpp:1396-1416
57
+ // runs after GatherBatches cpp:1387).
58
+ // 11. (driver/engine, optional) `for (const lf of scene.lensflares)
59
+ // lf?.PrepareRender?.(frustum)` (cpp:1419-1422; the JS lensflare shell has
60
+ // no method yet - pure no-op today).
61
+ // 12. (engine) reads registry collections directly: "ShadowCaster" (cascade
62
+ // gate cpp:614-621, RT push cpp:1544-1547), "VolumetricRenderable",
63
+ // "FroxelFogSettings", "MeshMorph" (engine may call
64
+ // `scene.componentRegistry.Clear("MeshMorph")` after bake),
65
+ // "ReflectionRenderable" (secondary gather cpp:1886-1895).
66
+ //
67
+ // One-shot registration trigger: after graph build/mutation call
68
+ // `scene.ReregisterEntities()` - covers objects + backgroundObjects + planets
69
+ // (entity-guarded) + cameraAttachmentParent (cpp:4064-4089, matching what
70
+ // OnListModified registers incrementally, cpp:3435-3491). uiObjects are
71
+ // intentionally excluded everywhere (cpp:3462 gate) - Carbon never registers
72
+ // or culls them.
73
+ // ---------------------------------------------------------------------------
74
+
16
75
  /** EveSpaceScene (eve/scene) - hand-maintained from schema shapeHash 571234b0.... */
17
76
  let _EveSpaceScene;
18
77
  new class extends _identity {
@@ -24,7 +83,7 @@ new class extends _identity {
24
83
  } = _applyDecs2311(this, [type.define({
25
84
  className: "EveSpaceScene",
26
85
  family: "eve/scene"
27
- })], [[[io, io.readwrite, type, type.int32, void 0, schema.enum("EveVisualizeMethod")], 16, "visualizeMethod"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap1ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap2ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap3ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaMixResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMapResPath"], [[io, io.persist, type, type.color], 16, "fogColor"], [[io, io.persist, type, type.vec3], 16, "sunDirection"], [[io, io.persist, type, type.color], 16, "ambientColor"], [[io, io.persistOnly, void 0, type.model("Tr2ShLightingManager")], 16, "shLightingManager"], [[io, io.read, void 0, type.objectRef("Tr2PostProcessAttributes")], 16, "combinedPostProcessAttributes"], [[io, io.read, void 0, type.objectRef("Tr2DataTextureManager")], 16, "dataTextureMgr"], [[io, io.readwrite, type, type.boolean], 16, "dynamicObjectReflectionEnabled"], [[io, io.read, void 0, type.objectRef("EveComponentRegistry")], 16, "componentRegistry"], [type.model("EveEffectRoot2"), 0, "cameraAttachmentParent"], [type.rawStruct("BluePy"), 0, "postProcessDebug"], [[io, io.persist, void 0, type.list("TriCurveSet")], 16, "curveSets"], [[io, io.persist, type, type.float32], 16, "defaultDiffuseRoughness"], [[io, io.persist, type, type.float32], 16, "fogStart"], [[io, io.persist, type, type.float32], 16, "fogEnd"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionIntensity"], [[io, io.read, void 0, type.list("EveDistanceField")], 16, "distanceFields"], [[io, io.persist, void 0, type.model("Tr2Effect")], 16, "backgroundEffect"], [[io, io.persist, type, type.float32], 16, "backgroundReflectionIntensity"], [[io, io.persist, type, type.float32], 16, "nebulaIntensity"], [[io, io.persist, type, type.boolean], 16, "display"], [[io, io.persist, type, type.boolean], 16, "backgroundRenderingEnabled"], [[io, io.persist, type, type.boolean], 16, "update"], [[io, io.readwrite, void 0, type.objectRef("Tr2ImpostorManager")], 16, "impostorManager"], [[io, io.persist, void 0, type.list("EveLensflare")], 16, "lensflares"], [[io, io.persist, void 0, type.list("Tr2ExternalParameter")], 16, "externalParameters"], [[io, io.persist, type, type.float32], 16, "fogMax"], [[io, io.read, void 0, type.list("EveSceneStaticParticles")], 16, "staticParticles"], [[io, io.readwrite, void 0, type.objectRef("Tr2DebugRenderer")], 16, "debugRenderer"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "objects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "uiObjects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "backgroundObjects"], [[io, io.persist, void 0, type.list("EvePlanet")], 16, "planets"], [[io, io.readwrite, void 0, type.objectRef("Tr2RaytracingManager")], 16, "raytracingManager"], [[io, io.notify, io, io.persist, type, type.color], 16, "reflectionBackLightingColor"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionBackLightingContrast"], [[io, io.notify, io, io.readwrite, void 0, type.objectRef("Tr2ReflectionProbe")], 16, "reflectionProbe"], [[io, io.read, void 0, type.objectRef("Tr2VolumetricsRenderer")], 16, "volumetricsRenderer"], [[io, io.persist, void 0, type.model("EveStarfield")], 16, "starfield"], [[io, io.persist, type, type.float32], 16, "planetScale"], [[io, io.persist, type, type.float32], 16, "planetCameraScale"], [[io, io.read, void 0, type.objectRef("Tr2SSSSS")], 16, "subSurfaceScattering"], [[io, io.notify, io, io.readwrite, type, type.int32, void 0, schema.enum("ShadowQuality")], 16, "shadowQualitySetting"], [[io, io.persist, type, type.color], 16, "sunDiffuseColor"], [[io, io.persist, type, type.color], 16, "sunDiffuseColorWithDynamicLights"], [[io, io.persist, type, type.quat], 16, "envMapRotation"], [[io, io.readwrite, void 0, type.objectRef("IEveBallpark")], 16, "ballpark"], [[io, io.persist, type, type.string], 16, "name"], [[io, io.persist, void 0, type.model("ITriVectorFunction")], 16, "sunBall"], [[io, io.persist, void 0, type.model("Tr2PostProcess2")], 16, "postprocess"], [[io, io.persist, void 0, type.model("EveVirtualCameraSystem")], 16, "virtualCameraSystem"], [[io, io.readwrite, void 0, type.objectRef("IEveSpaceObject2")], 16, "warpTunnel"], [[io, io.readwrite, type, type.float32], 16, "perFrameDebug"], [[io, io.persist, void 0, type.model("Tr2ShadowMap")], 16, "cascadedShadowMap"], [[io, io.read, type, type.float64], 16, "updateTime"], [[io, io.persist, type, type.boolean], 16, "useSunDiffuseColorWithDynamicLights"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap1"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap2"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap3"], [[carbon, carbon.method, impl, impl.adapted], 18, "Update"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickAsyncObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObjectAndAreaID"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickInfinity"], [[carbon, carbon.method, impl, impl.implemented], 18, "ReregisterEntities"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcessDebug"], [[carbon, carbon.method, impl, impl.implemented], 18, "UpdateScene"]], 0, void 0, CjsModel));
86
+ })], [[[io, io.readwrite, type, type.int32, void 0, schema.enum("EveVisualizeMethod")], 16, "visualizeMethod"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap1ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap2ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMap3ResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "lowQualityNebulaMixResPath"], [[io, io.notify, io, io.persist, type, type.string], 16, "envMapResPath"], [[io, io.persist, type, type.color], 16, "fogColor"], [[io, io.persist, type, type.vec3], 16, "sunDirection"], [[io, io.persist, type, type.color], 16, "ambientColor"], [[io, io.persistOnly, void 0, type.model("Tr2ShLightingManager")], 16, "shLightingManager"], [[io, io.read, void 0, type.objectRef("Tr2PostProcessAttributes")], 16, "combinedPostProcessAttributes"], [[io, io.read, void 0, type.objectRef("Tr2DataTextureManager")], 16, "dataTextureMgr"], [[io, io.readwrite, type, type.boolean], 16, "dynamicObjectReflectionEnabled"], [[io, io.read, void 0, type.objectRef("EveComponentRegistry")], 16, "componentRegistry"], [type.model("EveEffectRoot2"), 0, "cameraAttachmentParent"], [type.rawStruct("BluePy"), 0, "postProcessDebug"], [[io, io.persist, void 0, type.list("TriCurveSet")], 16, "curveSets"], [[io, io.persist, type, type.float32], 16, "defaultDiffuseRoughness"], [[io, io.persist, type, type.float32], 16, "fogStart"], [[io, io.persist, type, type.float32], 16, "fogEnd"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionIntensity"], [[io, io.read, void 0, type.list("EveDistanceField")], 16, "distanceFields"], [[io, io.persist, void 0, type.model("Tr2Effect")], 16, "backgroundEffect"], [[io, io.persist, type, type.float32], 16, "backgroundReflectionIntensity"], [[io, io.persist, type, type.float32], 16, "nebulaIntensity"], [[io, io.persist, type, type.boolean], 16, "display"], [[io, io.persist, type, type.boolean], 16, "backgroundRenderingEnabled"], [[io, io.persist, type, type.boolean], 16, "update"], [[io, io.readwrite, void 0, type.objectRef("Tr2ImpostorManager")], 16, "impostorManager"], [[io, io.persist, void 0, type.list("EveLensflare")], 16, "lensflares"], [[io, io.persist, void 0, type.list("Tr2ExternalParameter")], 16, "externalParameters"], [[io, io.persist, type, type.float32], 16, "fogMax"], [[io, io.read, void 0, type.list("EveSceneStaticParticles")], 16, "staticParticles"], [[io, io.readwrite, void 0, type.objectRef("Tr2DebugRenderer")], 16, "debugRenderer"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "objects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "uiObjects"], [[io, io.persist, void 0, type.list("IEveSpaceObject2")], 16, "backgroundObjects"], [[io, io.persist, void 0, type.list("EvePlanet")], 16, "planets"], [[io, io.readwrite, void 0, type.objectRef("Tr2RaytracingManager")], 16, "raytracingManager"], [[io, io.notify, io, io.persist, type, type.color], 16, "reflectionBackLightingColor"], [[io, io.notify, io, io.persist, type, type.float32], 16, "reflectionBackLightingContrast"], [[io, io.notify, io, io.readwrite, void 0, type.objectRef("Tr2ReflectionProbe")], 16, "reflectionProbe"], [[io, io.read, void 0, type.objectRef("Tr2VolumetricsRenderer")], 16, "volumetricsRenderer"], [[io, io.persist, void 0, type.model("EveStarfield")], 16, "starfield"], [[io, io.persist, type, type.float32], 16, "planetScale"], [[io, io.persist, type, type.float32], 16, "planetCameraScale"], [[io, io.read, void 0, type.objectRef("Tr2SSSSS")], 16, "subSurfaceScattering"], [[io, io.notify, io, io.readwrite, type, type.int32, void 0, schema.enum("ShadowQuality")], 16, "shadowQualitySetting"], [[io, io.persist, type, type.color], 16, "sunDiffuseColor"], [[io, io.persist, type, type.color], 16, "sunDiffuseColorWithDynamicLights"], [[io, io.persist, type, type.quat], 16, "envMapRotation"], [[io, io.readwrite, void 0, type.objectRef("IEveBallpark")], 16, "ballpark"], [[io, io.persist, type, type.string], 16, "name"], [[io, io.persist, void 0, type.model("ITriVectorFunction")], 16, "sunBall"], [[io, io.persist, void 0, type.model("Tr2PostProcess2")], 16, "postprocess"], [[io, io.persist, void 0, type.model("EveVirtualCameraSystem")], 16, "virtualCameraSystem"], [[io, io.readwrite, void 0, type.objectRef("IEveSpaceObject2")], 16, "warpTunnel"], [[io, io.readwrite, type, type.float32], 16, "perFrameDebug"], [[io, io.persist, void 0, type.model("Tr2ShadowMap")], 16, "cascadedShadowMap"], [[io, io.read, type, type.float64], 16, "updateTime"], [[io, io.persist, type, type.boolean], 16, "useSunDiffuseColorWithDynamicLights"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap1"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap2"], [[io, io.read, void 0, type.objectRef("ITr2TextureProvider")], 16, "envMap3"], [[carbon, carbon.method, impl, impl.adapted], 18, "Update"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickAsyncObject"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickObjectAndAreaID"], [[carbon, carbon.method, impl, impl.notImplemented], 18, "PickInfinity"], [[carbon, carbon.method, impl, impl.adapted, void 0, impl.reason("Carbon's g_enablePostProcessDebugging global becomes the scene-scoped enablePostProcessDebugging field; the debug payload is a plain object, null when off.")], 18, "UpdatePostProcessAttributes"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcess"], [[carbon, carbon.method, impl, impl.implemented], 18, "ReregisterEntities"], [[carbon, carbon.method, impl, impl.implemented], 18, "ClearComponentRegistry"], [[carbon, carbon.method, impl, impl.implemented], 18, "GetPostProcessDebug"], [[carbon, carbon.method, impl, impl.implemented], 18, "UpdateScene"]], 0, void 0, CjsModel));
28
87
  }
29
88
  /** m_visualizeMethod (EveVisualizeMethod - enum EveVisualizeMethod) [READWRITE, ENUM] */
30
89
  visualizeMethod = (_initProto(this), _init_visualizeMethod(this, 0));
@@ -59,8 +118,10 @@ new class extends _identity {
59
118
  /** m_shLightingManager (Tr2ShLightingManagerPtr) [PERSISTONLY] */
60
119
  shLightingManager = (_init_extra_ambientColor(this), _init_shLightingManager(this, null));
61
120
 
62
- /** m_combinedPostProcessAttributes (Tr2PostProcessAttributesPtr) [READ] */
63
- combinedPostProcessAttributes = (_init_extra_shLightingManager(this), _init_combinedPostProcessAttributes(this, null));
121
+ /** m_combinedPostProcessAttributes (Tr2PostProcessAttributesPtr) [READ] -
122
+ * default-constructed like Carbon's ctor CreateInstance (cpp:297); refreshed
123
+ * by UpdatePostProcessAttributes' re-export at MEDIUM_PRIORITY (cpp:407). */
124
+ combinedPostProcessAttributes = (_init_extra_shLightingManager(this), _init_combinedPostProcessAttributes(this, new _Tr2PostProcessAttrib()));
64
125
 
65
126
  /** m_dataTextureMgr (Tr2DataTextureManagerPtr) [READ] */
66
127
  dataTextureMgr = (_init_extra_combinedPostProcessAttributes(this), _init_dataTextureMgr(this, null));
@@ -71,8 +132,11 @@ new class extends _identity {
71
132
  /** m_componentRegistry (EveComponentRegistryPtr) [READ] */
72
133
  componentRegistry = (_init_extra_dynamicObjectReflectionEnabled(this), _init_componentRegistry(this, new _EveComponentRegistry()));
73
134
 
74
- /** m_cameraAttachmentParent (EveEffectRoot2Ptr) - protected Carbon scene entity. */
75
- cameraAttachmentParent = (_init_extra_componentRegistry(this), _init_cameraAttachmentParent(this, null));
135
+ /** m_cameraAttachmentParent (EveEffectRoot2Ptr) - protected Carbon scene
136
+ * entity, default-constructed like Carbon's ctor CreateInstance (cpp:287, no
137
+ * further setup applied). Consumers still optional-chain - deserialization
138
+ * may null it. */
139
+ cameraAttachmentParent = (_init_extra_componentRegistry(this), _init_cameraAttachmentParent(this, new _EveEffectRoot()));
76
140
 
77
141
  /** m_postProcessDebug (BluePy) - protected Carbon debug payload. */
78
142
  postProcessDebug = (_init_extra_cameraAttachmentParent(this), _init_postProcessDebug(this, null));
@@ -228,6 +292,74 @@ new class extends _identity {
228
292
  // Tr2Renderer view statics.
229
293
  updateContext = (_init_extra_envMap3(this), new _EveUpdateContext());
230
294
 
295
+ // Carbon m_sceneDefaultPostProcessAttributes (EveSpaceScene.h:640, ctor
296
+ // CreateInstance cpp:296): the scene default's attribute snapshot, refreshed
297
+ // by UpdatePostProcessAttributes each frame.
298
+ #sceneDefaultPostProcessAttributes = new _Tr2PostProcessAttrib();
299
+
300
+ // Carbon m_combinedPostProcess (EveSpaceScene.h:636): the merged output
301
+ // post-process, lazily constructed on first combine (cpp:367-370).
302
+ #combinedPostProcess = null;
303
+
304
+ // Carbon m_currentSunColor / m_currentNebulaIntensity /
305
+ // m_currentReflectionIntensity (EveSpaceScene.h:492-493/650, protected):
306
+ // outputs of the BeginRender lighting-override blend (cpp:1360-1362).
307
+ currentSunColor = vec4.create();
308
+ currentNebulaIntensity = 0;
309
+ currentReflectionIntensity = 0;
310
+
311
+ // Carbon g_eveSpaceSceneDynamicLighting (registered setting
312
+ // "eveSpaceSceneDynamicLighting", cpp:109-110, default false) - scoped to
313
+ // the scene instead of a module global.
314
+ dynamicLightingEnabled = false;
315
+
316
+ // Carbon g_enablePostProcessDebugging (registered setting
317
+ // "enablePostProcessDebugging", cpp:118-119, default false) - scoped to the
318
+ // scene instead of a module global.
319
+ enablePostProcessDebugging = false;
320
+
321
+ /**
322
+ * Stamps the per-frame frustum/threshold/LOD state onto the scene-owned
323
+ * update context (Carbon EveSpaceScene::Update cpp:475-484, identical to the
324
+ * already-updated fast path cpp:448-457). Carbon derives the frustum from
325
+ * the Tr2Renderer view statics and reads the thresholds from console vars
326
+ * divided by m_upscalingAmount (=1 by default, cpp:221); in CarbonEngineJS
327
+ * the driver derives the frustum from the same renderContext state it
328
+ * stamped and supplies the thresholds explicitly (pre-divided if it ever
329
+ * upscales). Defaults are the Carbon console-var defaults (cpp:75-84).
330
+ * The raytracing flag is Carbon's `m_shadowQuality == SHADOW_RAYTRACED &&
331
+ * m_enableShadows` (cpp:457/484) - the driver computes it; the scene does
332
+ * not. Stamps unconditionally: Carbon's same-frame fast path restamps
333
+ * regardless of m_update (cpp:444-462); only the cold path skips stamping
334
+ * when !m_update (cpp:466 precedes 475) - benign divergence.
335
+ * @param {Object} [options]
336
+ * @param {Object|null} [options.frustum] - a ready TriFrustum, held by reference
337
+ * @param {Number} [options.visibilityThreshold]
338
+ * @param {Number} [options.lowDetailThreshold]
339
+ * @param {Number} [options.mediumDetailThreshold]
340
+ * @param {Number} [options.highDetailThreshold]
341
+ * @param {Number} [options.lodFactor]
342
+ * @param {Boolean} [options.raytracingEnabled]
343
+ */
344
+ StampFrameContext({
345
+ frustum = null,
346
+ visibilityThreshold = 5,
347
+ lowDetailThreshold = 100,
348
+ mediumDetailThreshold = 400,
349
+ highDetailThreshold = 800,
350
+ lodFactor = 1,
351
+ raytracingEnabled = false
352
+ } = {}) {
353
+ const context = this.updateContext;
354
+ context.SetFrustum(frustum);
355
+ context.SetHighDetailThreshold(highDetailThreshold);
356
+ context.SetMediumDetailThreshold(mediumDetailThreshold);
357
+ context.SetLowDetailThreshold(lowDetailThreshold);
358
+ context.SetVisibilityThreshold(visibilityThreshold);
359
+ context.SetLodFactor(lodFactor);
360
+ context.raytracingEnabled = !!raytracingEnabled;
361
+ }
362
+
231
363
  /**
232
364
  * Per-frame scene update, ported from Carbon EveSpaceScene::Update: stamps the
233
365
  * scene-owned frame context (time, origin, data-texture manager), then drives
@@ -235,14 +367,14 @@ new class extends _identity {
235
367
  * starfield, static particles, data textures, distance fields, lensflares,
236
368
  * virtual camera system, curve sets, then all space/UI objects synchronous
237
369
  * first and asynchronous second (Carbon parallelizes the async pass on a task
238
- * group; JS runs it sequentially). Finally reads the sun direction from the
239
- * sun ball.
370
+ * group; JS runs it sequentially). Then combines the post-process attributes
371
+ * (cpp:584) and finally reads the sun direction from the sun ball
372
+ * (cpp:589-596).
240
373
  *
241
- * Adapted - deferred vs Carbon: the recording-frame dedup fast path, frustum
242
- * derivation (TriFrustum unported; context.frustum stays null), detail
243
- * threshold / LOD stamping (console-var globals + upscaling), raytracing flag,
244
- * planet update (planet view-matrix swap unported), post-process attribute
245
- * combine, and main-thread action flush.
374
+ * Adapted - deferred vs Carbon: the recording-frame dedup fast path,
375
+ * frustum/threshold/LOD/raytracing stamping (now the driver's job via
376
+ * StampFrameContext, called BEFORE Update), planet update (planet
377
+ * view-matrix swap unported), and main-thread action flush (N/A).
246
378
  * @param {Number} realTime
247
379
  * @param {Number} simTime
248
380
  */
@@ -292,6 +424,10 @@ new class extends _identity {
292
424
  object?.UpdateAsyncronous?.(context);
293
425
  }
294
426
 
427
+ // Combine the post-process attributes (Carbon cpp:584, after the async
428
+ // pass + ExecuteMainThreadActions cpp:581 and before the sun read).
429
+ this.UpdatePostProcessAttributes();
430
+
295
431
  // Sun direction from the sun ball: the normalized sun position, negated
296
432
  // (Carbon: m_sunData.DirWorld = -Normalize(sunDirection)).
297
433
  if (this.sunBall?.Update) {
@@ -322,18 +458,240 @@ new class extends _identity {
322
458
  throw new Error("EveSpaceScene.PickInfinity is not implemented in CarbonEngineJS.");
323
459
  }
324
460
 
461
+ /**
462
+ * The per-frame CPU visibility pass, ported from the [VISIBILITY] block of
463
+ * Carbon EveSpaceScene::GatherBatches (EveSpaceScene.cpp:1443-1467; the
464
+ * enclosing display gate is BeginRender cpp:1299-1302). Carbon's
465
+ * Tr2ParallelDo loops (objects cpp:1445-1447, staticParticles cpp:1454-1456,
466
+ * planets cpp:1458-1460) run sequentially in the same order; the lensflare
467
+ * loop is sequential in Carbon too (cpp:1462-1466). LOD stamping (lodLevel,
468
+ * isVisible, pixel diameters) happens INSIDE each object's UpdateVisibility;
469
+ * per-object display gates live there too - the scene does not pre-filter.
470
+ * uiObjects are never visited (Carbon never culls them). The camera parent's
471
+ * SetTransform is pure decomposition (EveEffectRoot2.cpp:677-680 Decompose)
472
+ * - no composition, so no row-vector operand swap here; this per-gather
473
+ * Sync/Async pair is the camera parent's ONLY update, so its world transform
474
+ * is the camera pose of the frame being gathered (cpp:1449-1452).
475
+ * @param {Float32Array} inverseView - the inverse view matrix
476
+ * (updateContext.renderContext.GetInverseViewTransform(); Carbon reads the
477
+ * Tr2Renderer static at cpp:1449)
478
+ */
479
+ UpdateVisibility(inverseView) {
480
+ if (!this.display) {
481
+ return;
482
+ }
483
+ for (const object of this.objects) {
484
+ object?.UpdateVisibility?.(this.updateContext, IDENTITY);
485
+ }
486
+ this.cameraAttachmentParent?.SetTransform?.(inverseView);
487
+ this.cameraAttachmentParent?.UpdateSyncronous?.(this.updateContext);
488
+ this.cameraAttachmentParent?.UpdateAsyncronous?.(this.updateContext);
489
+ this.cameraAttachmentParent?.UpdateVisibility?.(this.updateContext, IDENTITY);
490
+ for (const staticParticles of this.staticParticles) {
491
+ staticParticles?.UpdateVisibility?.(this.updateContext);
492
+ }
493
+ for (const planet of this.planets) {
494
+ planet?.UpdateZOnlyVisibility?.(this.updateContext);
495
+ }
496
+
497
+ // Sequential in Carbon too: "until we have proper support for multiple
498
+ // lensflares we just do it in a list" (cpp:1462-1466).
499
+ for (const lensflare of this.lensflares) {
500
+ lensflare?.UpdateVisibility?.(this.updateContext);
501
+ }
502
+ }
503
+
325
504
  /** Gathers batchable renderables from the scene's objects for the batch
326
- * collection pass. Carbon gathers these inline in EveSpaceScene::GatherBatches
327
- * (EveSpaceScene.cpp:1433-1514): objects self-filter on the visibility flags
328
- * stamped by the update pass, so this aggregation stays GPU-free. */
505
+ * collection pass - the [GATHER] block of Carbon
506
+ * EveSpaceScene::GatherBatches (EveSpaceScene.cpp:1470-1507): m_objects in
507
+ * list order (cpp:1470-1475), then cameraAttachmentParent pushed LAST
508
+ * (cpp:1476), then the staticParticles leg (cpp:1504-1507; Carbon signature
509
+ * `GetRenderables(frustum, renderables)`, EveSceneStaticParticles.h - kept
510
+ * with the out-parameter last per convention). Objects self-filter on the
511
+ * visibility flags stamped by UpdateVisibility, so the array handed to
512
+ * CjsBatchManager.Collect is pre-culled and this aggregation stays GPU-free.
513
+ * The impostor-manager argument (cpp:1478-1502) is dropped - engine-owned.
514
+ * Gather order matters downstream: the opaque accumulator receives batches
515
+ * in gather order before Finalize sorts. */
329
516
  GetRenderables(out = []) {
517
+ if (!this.display) {
518
+ return out;
519
+ }
330
520
  for (const object of this.objects) object?.GetRenderables?.(out);
331
521
  this.cameraAttachmentParent?.GetRenderables?.(out);
522
+ for (const staticParticles of this.staticParticles) {
523
+ staticParticles?.GetRenderables?.(this.updateContext.GetFrustum(), out);
524
+ }
332
525
  return out;
333
526
  }
334
527
 
335
- /** Carbon method ReregisterEntities (MAP_METHOD_AND_WRAP). */
528
+ /**
529
+ * Refreshes the scene default's attribute snapshot, gathers every registered
530
+ * PostProcessOwner's attributes, priority-blends them into the combined
531
+ * post-process, copies the six engine effects through from the scene
532
+ * default, and re-exports the result (Carbon
533
+ * EveSpaceScene::UpdatePostProcessAttributes, EveSpaceScene.cpp:346-413).
534
+ * Sort is descending by priority (cpp:372-377); Carbon's std::sort is
535
+ * unstable while JS sort is stable - equal-priority ties keep registry
536
+ * insertion order, which is blend-order-independent for every Sum-accumulated
537
+ * attribute (the whole tie group is normalized together); only MaxWeight
538
+ * ties at exactly equal weight (string paths / bools / DoF shape) could
539
+ * differ from C++.
540
+ */
541
+ UpdatePostProcessAttributes() {
542
+ if (!this.display) {
543
+ return;
544
+ }
545
+
546
+ // Scene default refreshed BEFORE the gather (cpp:354); FromPostProcess
547
+ // handles a null postprocess (reset + return).
548
+ this.#sceneDefaultPostProcessAttributes.FromPostProcess(this.postprocess, _Tr2PostProcessAttrib.SCENE_DEFAULT_PRIORITY, 1.0);
549
+ const sources = [];
550
+ for (const owner of this.componentRegistry?.GetComponents(EveComponentType.PostProcessOwner) ?? []) {
551
+ // Carbon pushes unguarded (cpp:358-361); JS ducks may return null.
552
+ const attributes = owner?.GetPostProcessAttributes?.();
553
+ if (attributes) {
554
+ sources.push(attributes);
555
+ }
556
+ }
557
+
558
+ // Scene default appended LAST (cpp:363).
559
+ sources.push(this.#sceneDefaultPostProcessAttributes);
560
+
561
+ // The list is never empty (default always pushed) so Carbon's else-branch
562
+ // (cpp:411) is unreachable; the guard is kept for shape fidelity.
563
+ if (sources.length) {
564
+ this.#combinedPostProcess ??= new _Tr2PostProcess();
565
+ sources.sort((a, b) => b.priority - a.priority);
566
+ if (this.enablePostProcessDebugging) {
567
+ const observer = _Tr2PostProcessAttrib.CreateDebugObserver();
568
+ _Tr2PostProcessAttrib.MergeInto(this.#combinedPostProcess, sources, observer);
569
+ this.postProcessDebug = observer.GetDict();
570
+ } else {
571
+ _Tr2PostProcessAttrib.MergeInto(this.#combinedPostProcess, sources);
572
+ this.postProcessDebug = null;
573
+ }
574
+
575
+ // Engine-effect copy-through from the scene default only - NOT blended
576
+ // (cpp:389-406).
577
+ if (this.postprocess) {
578
+ this.#combinedPostProcess.SetDynamicExposure(this.postprocess.GetDynamicExposureIfAvailable?.() ?? null);
579
+ this.#combinedPostProcess.SetTaa(this.postprocess.GetTaaIfAvailable?.() ?? null);
580
+ this.#combinedPostProcess.SetTonemapping(this.postprocess.GetTonemappingIfAvailable?.() ?? null);
581
+ this.#combinedPostProcess.SetFog(this.postprocess.GetFogIfAvailable?.() ?? null);
582
+ this.#combinedPostProcess.SetGodRays(this.postprocess.GetGodRaysIfAvailable?.() ?? null);
583
+ this.#combinedPostProcess.SetGenericEffect(this.postprocess.GetGenericEffectIfAvailable?.() ?? null);
584
+ } else {
585
+ this.#combinedPostProcess.SetDynamicExposure(null);
586
+ this.#combinedPostProcess.SetTaa(null);
587
+ this.#combinedPostProcess.SetTonemapping(null);
588
+ this.#combinedPostProcess.SetFog(null);
589
+ this.#combinedPostProcess.SetGodRays(null);
590
+ this.#combinedPostProcess.SetGenericEffect(null);
591
+ }
592
+
593
+ // Re-export the combined result as an attributes object at
594
+ // MEDIUM_PRIORITY - consumed by nested-scene composition (cpp:407).
595
+ (this.combinedPostProcessAttributes ??= new _Tr2PostProcessAttrib()).FromPostProcess(this.#combinedPostProcess, _Tr2PostProcessAttrib.MEDIUM_PRIORITY, 1.0);
596
+ } else {
597
+ this.#combinedPostProcess = null;
598
+ }
599
+ }
600
+
601
+ /** Carbon method GetPostProcess (EveSpaceScene.cpp:420-427): the combined
602
+ * post-process, or null while the scene is not displayed. */
603
+ GetPostProcess() {
604
+ if (!this.display) {
605
+ return null;
606
+ }
607
+ return this.#combinedPostProcess;
608
+ }
609
+
610
+ /**
611
+ * Blends every registered EveLightingOverride against the scene baseline and
612
+ * stamps currentSunColor / currentNebulaIntensity /
613
+ * currentReflectionIntensity - the lighting-override block of Carbon
614
+ * EveSpaceScene::BeginRender (EveSpaceScene.cpp:1333-1363). The baseline is
615
+ * appended AFTER the sort at raw priority -1 - one below
616
+ * SCENE_DEFAULT_PRIORITY=0, outside the legal enum range (Carbon casts -1,
617
+ * cpp:1343) - so it always sits last. Scalar/color math only - no matrix
618
+ * compositions, no row-vector swaps anywhere in this method. Same
619
+ * stable-sort note as UpdatePostProcessAttributes - here fully benign, the
620
+ * blend is symmetric within a tie group.
621
+ */
622
+ BlendLightingOverrides() {
623
+ if (!this.display) {
624
+ return;
625
+ }
626
+ const overrides = [];
627
+ for (const component of this.componentRegistry?.GetComponents(EveComponentType.EveLightingOverride) ?? []) {
628
+ overrides.push(component.GetOverrides());
629
+ }
630
+ overrides.sort((a, b) => b.priority - a.priority);
631
+
632
+ // Baseline (cpp:1342-1357): the scene's own sun/nebula/reflection state,
633
+ // sun color normalized by its max channel (all four components scaled).
634
+ const sunColorSource = this.useSunDiffuseColorWithDynamicLights && this.dynamicLightingEnabled ? this.sunDiffuseColorWithDynamicLights : this.sunDiffuseColor;
635
+ const sunIntensity = Math.max(sunColorSource[0], sunColorSource[1], sunColorSource[2]);
636
+ const baselineSunColor = vec4.create();
637
+ if (sunIntensity !== 0) {
638
+ vec4.scale(baselineSunColor, sunColorSource, 1 / sunIntensity);
639
+ } else {
640
+ vec4.copy(baselineSunColor, sunColorSource);
641
+ }
642
+ overrides.push({
643
+ priority: -1,
644
+ intensity: 1,
645
+ value: {
646
+ sunColor: baselineSunColor,
647
+ sunIntensity,
648
+ backgroundIntensity: this.nebulaIntensity,
649
+ reflectionIntensity: this.reflectionIntensity
650
+ }
651
+ });
652
+ const over = _EveSpaceScene.#SimplePriorityBlend(overrides);
653
+ vec4.scale(this.currentSunColor, over.sunColor, over.sunIntensity);
654
+ this.currentNebulaIntensity = over.backgroundIntensity;
655
+ this.currentReflectionIntensity = over.reflectionIntensity;
656
+ }
657
+
658
+ /**
659
+ * Drives the injected light manager through Carbon's dynamic-light gather
660
+ * (EveSpaceScene::BeginRender, EveSpaceScene.cpp:1396-1416, AFTER
661
+ * GatherBatches cpp:1387): shadow quality, clear (runs even with zero owners
662
+ * - stale lights must drop), frustum, LOD cutoff, then every registered
663
+ * LightOwner's GetLights (Carbon Tr2ParallelFor chunk-20 cpp:1405-1413; JS
664
+ * sequential in collection order), then ResolveLightData. No JS
665
+ * Tr2LightManager class exists - the manager is a duck and every manager
666
+ * call is optional-chained so a partial duck still gets the owner loop.
667
+ * Carbon runs the block only when a manager instance exists (dynamic
668
+ * lighting on) - a null manager is a no-op. The recording frame number
669
+ * Carbon passes to SetShadowQuality and the renderContext it passes to Clear
670
+ * are engine recording state - the JS Clear receives the frame's
671
+ * renderContext for ducks that want it.
672
+ * @param {Object|null} lightManager
673
+ */
674
+ GatherLights(lightManager) {
675
+ if (!lightManager || !this.display) {
676
+ return;
677
+ }
678
+ lightManager.SetShadowQuality?.(this.shadowQualitySetting);
679
+ lightManager.Clear?.(this.updateContext.renderContext);
680
+ lightManager.SetFrustum?.(this.updateContext.GetFrustum());
681
+ lightManager.AdjustLightCutoff?.(this.updateContext.GetLodFactor());
682
+ for (const owner of this.componentRegistry?.GetComponents(EveComponentType.LightOwner) ?? []) {
683
+ owner?.GetLights?.(lightManager);
684
+ }
685
+ lightManager.ResolveLightData?.();
686
+ }
687
+
688
+ /** Carbon method ReregisterEntities (MAP_METHOD_AND_WRAP, cpp:4064-4089).
689
+ * Guarded no-op after ClearComponentRegistry has nulled the registry
690
+ * (destroy-only path; Carbon would never call this afterwards). */
336
691
  ReregisterEntities() {
692
+ if (!this.componentRegistry) {
693
+ return;
694
+ }
337
695
  for (const collection of [this.objects, this.backgroundObjects, this.planets]) {
338
696
  for (const object of collection) {
339
697
  if (object instanceof _EveEntity) {
@@ -346,6 +704,17 @@ new class extends _identity {
346
704
  }
347
705
  }
348
706
 
707
+ /** Carbon method ClearComponentRegistry (EveSpaceScene.cpp:4091-4099, called
708
+ * from the destructor cpp:322). Entity component-state is deliberately NOT
709
+ * cleared beyond what Clear() does - either the scene is being destroyed
710
+ * (entities go too) or entities move to another scene and re-register there.
711
+ * The JS registry Clear() additionally detaches entity.registry when it
712
+ * points at this registry - strictly more hygienic than Carbon; kept. */
713
+ ClearComponentRegistry() {
714
+ this.componentRegistry?.Clear();
715
+ this.componentRegistry = null;
716
+ }
717
+
349
718
  /** Carbon method GetPostProcessDebug (MAP_METHOD_AND_WRAP). */
350
719
  GetPostProcessDebug() {
351
720
  return this.postProcessDebug;
@@ -355,6 +724,23 @@ new class extends _identity {
355
724
  UpdateScene(time) {
356
725
  return this.Update(time, time);
357
726
  }
727
+
728
+ /**
729
+ * Carbon SimplePriorityBlend (PriorityBlend.h:371-413) specialized to the
730
+ * IEveLightingOverride::Overrides value type
731
+ * { sunColor: vec4, sunIntensity, backgroundIntensity, reflectionIntensity }
732
+ * (EveChildLightingOverride.h:15-32) - `+` and `* weight` componentwise.
733
+ * Walks the (already priority-desc-sorted) list in equal-priority groups:
734
+ * factor = (1 / max(groupTotal, 1)) * remainingWeight
735
+ * then subtracts the UNCLAMPED group total from remainingWeight. Two quirks
736
+ * preserved exactly: (a) a group with total intensity 0.3 contributes at
737
+ * weight 0.3*remaining and leaves 0.7 for lower priorities; (b) a group with
738
+ * total 2 is normalized to consume exactly remainingWeight and terminates
739
+ * (remaining goes to -1).
740
+ * @param {Array} sources - [{ priority, intensity, value }] sorted high->low
741
+ * @returns {{ sunColor: Float32Array, sunIntensity: Number,
742
+ * backgroundIntensity: Number, reflectionIntensity: Number }}
743
+ */
358
744
  }];
359
745
  EveVisualizeMethod = Object.freeze({
360
746
  VM_NONE: 0,
@@ -372,6 +758,47 @@ new class extends _identity {
372
758
  SHADOW_HIGH: 2,
373
759
  SHADOW_RAYTRACED: 3
374
760
  });
761
+ #SimplePriorityBlend(sources) {
762
+ const result = {
763
+ sunColor: vec4.create(),
764
+ sunIntensity: 0,
765
+ backgroundIntensity: 0,
766
+ reflectionIntensity: 0
767
+ };
768
+ let remainingWeight = 1;
769
+ for (let first = 0; first < sources.length;) {
770
+ // The range of sources sharing the current priority.
771
+ let last = first + 1;
772
+ while (last < sources.length && sources[last].priority === sources[first].priority) {
773
+ last++;
774
+ }
775
+ let totalPriorityIntensity = 0;
776
+ for (let index = first; index < last; index++) {
777
+ totalPriorityIntensity += sources[index].intensity;
778
+ }
779
+ if (totalPriorityIntensity === 0) {
780
+ first = last;
781
+ continue;
782
+ }
783
+ const normalizationFactor = 1 / Math.max(totalPriorityIntensity, 1) * remainingWeight;
784
+ for (let index = first; index < last; index++) {
785
+ const weight = sources[index].intensity * normalizationFactor;
786
+ const value = sources[index].value;
787
+ vec4.scaleAndAdd(result.sunColor, result.sunColor, value.sunColor, weight);
788
+ result.sunIntensity += value.sunIntensity * weight;
789
+ result.backgroundIntensity += value.backgroundIntensity * weight;
790
+ result.reflectionIntensity += value.reflectionIntensity * weight;
791
+ }
792
+
793
+ // Subtracts the UNCLAMPED total (PriorityBlend.h:405).
794
+ remainingWeight -= totalPriorityIntensity;
795
+ first = last;
796
+ if (remainingWeight <= 0) {
797
+ break;
798
+ }
799
+ }
800
+ return result;
801
+ }
375
802
  constructor() {
376
803
  super(_EveSpaceScene), _initClass();
377
804
  }