diff --git a/src/document/migrate-scene-document.ts b/src/document/migrate-scene-document.ts index 5e6cf6f0..6121207d 100644 --- a/src/document/migrate-scene-document.ts +++ b/src/document/migrate-scene-document.ts @@ -196,6 +196,7 @@ import { FOLIAGE_FOUNDATION_SCENE_DOCUMENT_VERSION, FOLIAGE_MASKS_SCENE_DOCUMENT_VERSION, FOLIAGE_QUALITY_SCENE_DOCUMENT_VERSION, + FOLIAGE_WIND_SCENE_DOCUMENT_VERSION, GOD_RAYS_SCENE_DOCUMENT_VERSION, GOD_RAYS_SOURCE_SIZE_SCENE_DOCUMENT_VERSION, DEFAULT_PROJECT_NAME, @@ -1238,7 +1239,27 @@ function readAdvancedRenderingSettings( "world.advancedRendering.foliage.maxDistanceMultiplier", defaults.foliage.maxDistanceMultiplier ), - shadows: foliageShadowMode + shadows: foliageShadowMode, + windEnabled: readOptionalBoolean( + foliage?.windEnabled, + "world.advancedRendering.foliage.windEnabled", + defaults.foliage.windEnabled + ), + windStrength: readOptionalFiniteNumber( + foliage?.windStrength, + "world.advancedRendering.foliage.windStrength", + defaults.foliage.windStrength + ), + windSpeed: readOptionalFiniteNumber( + foliage?.windSpeed, + "world.advancedRendering.foliage.windSpeed", + defaults.foliage.windSpeed + ), + windDirectionDegrees: readOptionalFiniteNumber( + foliage?.windDirectionDegrees, + "world.advancedRendering.foliage.windDirectionDegrees", + defaults.foliage.windDirectionDegrees + ) }), fogPath, waterPath, @@ -6879,7 +6900,8 @@ export function migrateSceneDocument(source: unknown): SceneDocument { source.version !== SPLINE_CORRIDOR_JUNCTION_SHAPE_SCENE_DOCUMENT_VERSION && source.version !== NPC_TARGETING_SCENE_DOCUMENT_VERSION && source.version !== CUSTOM_PBR_MATERIALS_SCENE_DOCUMENT_VERSION && - source.version !== LENS_FLARE_SCENE_DOCUMENT_VERSION + source.version !== LENS_FLARE_SCENE_DOCUMENT_VERSION && + source.version !== FOLIAGE_WIND_SCENE_DOCUMENT_VERSION ) { throw new Error( `Unsupported scene document version: ${String(source.version)}.` diff --git a/src/document/scene-document.ts b/src/document/scene-document.ts index b42a09cd..7563b8c3 100644 --- a/src/document/scene-document.ts +++ b/src/document/scene-document.ts @@ -36,7 +36,8 @@ import { type FoliagePrototypeRegistry } from "../foliage/foliage"; -export const SCENE_DOCUMENT_VERSION = 111 as const; +export const SCENE_DOCUMENT_VERSION = 112 as const; +export const FOLIAGE_WIND_SCENE_DOCUMENT_VERSION = 112 as const; export const LENS_FLARE_SCENE_DOCUMENT_VERSION = 111 as const; export const CUSTOM_PBR_MATERIALS_SCENE_DOCUMENT_VERSION = 110 as const; export const SPLINE_CORRIDOR_JUNCTION_SHAPE_SCENE_DOCUMENT_VERSION = 109 as const; diff --git a/src/document/world-settings.ts b/src/document/world-settings.ts index 964762d7..afd930e5 100644 --- a/src/document/world-settings.ts +++ b/src/document/world-settings.ts @@ -573,7 +573,11 @@ export function createDefaultFoliageQualitySettings(): FoliageQualitySettings { enabled: DEFAULT_FOLIAGE_QUALITY_ENABLED, densityMultiplier: DEFAULT_FOLIAGE_QUALITY_DENSITY_MULTIPLIER, maxDistanceMultiplier: DEFAULT_FOLIAGE_QUALITY_MAX_DISTANCE_MULTIPLIER, - shadows: DEFAULT_FOLIAGE_QUALITY_SHADOWS + shadows: DEFAULT_FOLIAGE_QUALITY_SHADOWS, + windEnabled: DEFAULT_FOLIAGE_QUALITY_WIND_ENABLED, + windStrength: DEFAULT_FOLIAGE_QUALITY_WIND_STRENGTH, + windSpeed: DEFAULT_FOLIAGE_QUALITY_WIND_SPEED, + windDirectionDegrees: DEFAULT_FOLIAGE_QUALITY_WIND_DIRECTION_DEGREES }; } @@ -586,25 +590,51 @@ export function resolveFoliageQualitySettings( return defaults; } + const candidate = settings as Partial; + return { - enabled: settings.enabled, - densityMultiplier: Number.isFinite(settings.densityMultiplier) + enabled: + typeof candidate.enabled === "boolean" + ? candidate.enabled + : defaults.enabled, + densityMultiplier: Number.isFinite(candidate.densityMultiplier) ? clamp( - settings.densityMultiplier, + candidate.densityMultiplier!, MIN_FOLIAGE_QUALITY_DENSITY_MULTIPLIER, MAX_FOLIAGE_QUALITY_DENSITY_MULTIPLIER ) : defaults.densityMultiplier, - maxDistanceMultiplier: Number.isFinite(settings.maxDistanceMultiplier) + maxDistanceMultiplier: Number.isFinite(candidate.maxDistanceMultiplier) ? clamp( - settings.maxDistanceMultiplier, + candidate.maxDistanceMultiplier!, MIN_FOLIAGE_QUALITY_MAX_DISTANCE_MULTIPLIER, MAX_FOLIAGE_QUALITY_MAX_DISTANCE_MULTIPLIER ) : defaults.maxDistanceMultiplier, - shadows: isFoliageQualityShadowMode(settings.shadows) - ? settings.shadows - : defaults.shadows + shadows: isFoliageQualityShadowMode(candidate.shadows) + ? candidate.shadows + : defaults.shadows, + windEnabled: + typeof candidate.windEnabled === "boolean" + ? candidate.windEnabled + : defaults.windEnabled, + windStrength: Number.isFinite(candidate.windStrength) + ? clamp( + candidate.windStrength!, + MIN_FOLIAGE_QUALITY_WIND_STRENGTH, + MAX_FOLIAGE_QUALITY_WIND_STRENGTH + ) + : defaults.windStrength, + windSpeed: Number.isFinite(candidate.windSpeed) + ? clamp( + candidate.windSpeed!, + MIN_FOLIAGE_QUALITY_WIND_SPEED, + MAX_FOLIAGE_QUALITY_WIND_SPEED + ) + : defaults.windSpeed, + windDirectionDegrees: Number.isFinite(candidate.windDirectionDegrees) + ? normalizeDegrees(candidate.windDirectionDegrees!) + : defaults.windDirectionDegrees }; } @@ -624,7 +654,11 @@ export function areFoliageQualitySettingsEqual( left.enabled === right.enabled && left.densityMultiplier === right.densityMultiplier && left.maxDistanceMultiplier === right.maxDistanceMultiplier && - left.shadows === right.shadows + left.shadows === right.shadows && + left.windEnabled === right.windEnabled && + left.windStrength === right.windStrength && + left.windSpeed === right.windSpeed && + left.windDirectionDegrees === right.windDirectionDegrees ); }