serializeStage function

void serializeStage(
  1. Scene scene,
  2. SceneDocument document
)

Reads scene's stage render settings back into document, writing the look into the stage's environment resource (creating and linking one when the stage has none).

The reverse of realizeStage. An environment the realizer produced recovers its source spec, and an fmat sky loaded through loadFmatSky recovers its source path plus every parameter assigned through its typed setters; a hand-built EnvironmentMap serializes as the studio default and a custom ShaderSkySource is dropped, each with a warning.

Implementation

void serializeStage(Scene scene, SceneDocument document) {
  final stage = document.stage;
  stage.antiAliasingMode = scene.antiAliasingMode.name;
  stage.renderScale = scene.renderScale;
  stage.filterQuality = scene.filterQuality.name;

  final resource = _ensureStageEnvironment(document);
  resource.environmentIntensity = scene.environmentIntensity;
  resource.exposure = scene.exposure;
  resource.toneMapping = scene.toneMapping.name;
  resource.agxWhite = scene.agxWhite;
  resource.agxContrast = scene.agxContrast;
  final transform = scene.environmentTransform.storage;
  // TODO(environment-transform): store a full orientation in the document so
  // serialization does not discard rotations outside world Y.
  resource.environmentRotationY = math.atan2(transform[6], transform[0]);
  resource.effects = _effectSpecFromSettings(
    EnvironmentSettings.fromScene(scene),
  );
  resource.overridesEffects = true;

  final skyEnvironment = scene.skyEnvironment;
  if (skyEnvironment == null) {
    resource.skyEnvironment = null;
    final environment = scene.environment;
    var spec = environment == null ? null : _environmentSpec[environment];
    if (spec == null && environment != null) {
      // An environment the app loaded itself still recovers when it carries
      // its asset-path stamp (EnvironmentMap.fromEquirectImageAsset).
      final assetPath = environmentAssetPathOf(environment);
      if (assetPath != null) spec = AssetEnvironment(AssetRef(assetPath));
    }
    if (spec != null) {
      resource.environment = spec;
    } else {
      if (environment != null) {
        debugPrint(
          'fscene: the scene environment was not produced by realizeStage '
          'or EnvironmentMap.fromEquirectImageAsset and cannot be recovered; '
          'serializing the studio default',
        );
      }
      resource.environment = const StudioEnvironment();
    }
  } else {
    final source = _serializeSkySource(skyEnvironment.source);
    // Only serialize a sun driven by this sky source.
    final skySun = identical(scene.sunLight?.source, skyEnvironment.source)
        ? scene.sunLight
        : null;
    resource.skyEnvironment = source == null
        ? null
        : SkyEnvironmentSpec(
            source,
            refresh: skyEnvironment.refresh.name,
            intervalSeconds: skyEnvironment.interval.inMicroseconds / 1e6,
            faceResolution: skyEnvironment.faceResolution,
            equirectWidth: skyEnvironment.equirectWidth,
            sunLight: skySun == null ? null : _serializeSunLight(skySun),
          );
  }

  final skybox = scene.skybox;
  if (skybox == null) {
    resource.skybox = null;
  } else {
    final source = _serializeSkySource(skybox.source);
    resource.skybox = source == null
        ? null
        : SkyboxSpec(source, intensity: skybox.intensity);
  }
}