Skip to content

Commit 4d321a8

Browse files
committed
Normalize demoted common material UV transforms
1 parent 1d1bf83 commit 4d321a8

5 files changed

Lines changed: 39 additions & 22 deletions

File tree

src/PlateauResoniteLink/Targets/Resonite/ResoniteDynamicMaterialUvNormalizer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ public static bool ShouldNormalizeTextureTransform(ResoniteMaterialBinding mater
1515
return material.MaterialType == ResoniteMaterialType.Standard
1616
&& material.Projection == ResoniteMaterialProjection.Uv
1717
&& (material.AssetScope != ResoniteMaterialAssetScope.Common
18-
|| material.TextureSourceKind == ResoniteTextureSourceKind.Dataset)
18+
|| material.TextureSourceKind == ResoniteTextureSourceKind.Dataset
19+
|| ResoniteSceneMaterialConventions.ShouldDemoteBundledCommonMaterial(material))
1920
&& HasNormalizableTextureTransform(material);
2021
}
2122

src/PlateauResoniteLink/Targets/Resonite/ResoniteSceneMaterialConventions.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,16 @@ public static ResoniteMaterialBinding NormalizeBatchGroupedMaterialBinding(Reson
8383
ArgumentNullException.ThrowIfNull(material);
8484
material = ResoniteDynamicMaterialUvNormalizer.NormalizeMaterialBinding(material);
8585

86-
if (material.AssetScope == ResoniteMaterialAssetScope.Common
87-
&& material.MaterialType == ResoniteMaterialType.Standard
88-
&& material.TexturePayload is null
89-
&& material.TerrainOverlay is null
90-
&& material.TextureSourceKind == ResoniteTextureSourceKind.Bundled
91-
&& !string.IsNullOrWhiteSpace(material.Family)
92-
&& (!IsWhiteBaseColor(material.BaseColor)
93-
|| HasNonDefaultBundledTextureTransform(material)
94-
|| material.DepthOffset is not null))
86+
if (ShouldDemoteBundledCommonMaterial(material))
9587
{
96-
return material with
88+
ResoniteMaterialBinding demotedMaterial = material with
9789
{
9890
AssetBinding = material.CommonMaterial is { } commonMaterial
9991
? ResoniteMaterialAssetBinding.PresentationCommon(commonMaterial)
10092
: ResoniteMaterialAssetBinding.Presentation,
10193
};
94+
95+
return ResoniteDynamicMaterialUvNormalizer.NormalizeMaterialBinding(demotedMaterial);
10296
}
10397

10498
if (material.AssetScope == ResoniteMaterialAssetScope.PresentationSlotScoped
@@ -119,6 +113,21 @@ public static ResoniteMaterialBinding NormalizeBatchGroupedMaterialBinding(Reson
119113
return material;
120114
}
121115

116+
internal static bool ShouldDemoteBundledCommonMaterial(ResoniteMaterialBinding material)
117+
{
118+
ArgumentNullException.ThrowIfNull(material);
119+
120+
return material.AssetScope == ResoniteMaterialAssetScope.Common
121+
&& material.MaterialType == ResoniteMaterialType.Standard
122+
&& material.TexturePayload is null
123+
&& material.TerrainOverlay is null
124+
&& material.TextureSourceKind == ResoniteTextureSourceKind.Bundled
125+
&& !string.IsNullOrWhiteSpace(material.Family)
126+
&& (!IsWhiteBaseColor(material.BaseColor)
127+
|| HasNonDefaultBundledTextureTransform(material)
128+
|| material.DepthOffset is not null);
129+
}
130+
122131
public static TextureIdentity CreateTextureIdentity(TextureMemberRole role)
123132
{
124133
return new TextureIdentity(role switch

tests/PlateauResoniteLink.Tests/Targets/NonDemCityObjectBakerTests.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ public async Task FlushAllAsyncKeepsCommonMaterialsAsSeparateSubmeshesWhileAtlas
351351
}
352352

353353
[Fact]
354-
public async Task FlushAllAsyncKeepsBundledFacadeCommonTransformOnMaterial()
354+
public async Task FlushAllAsyncDemotesBundledFacadeCommonTransformToMeshUv()
355355
{
356356
NonDemCityObjectBaker baker = CreateBaker(maxAtlasSize: 32, tilePaddingPixels: 1);
357357

@@ -362,11 +362,14 @@ public async Task FlushAllAsyncKeepsBundledFacadeCommonTransformOnMaterial()
362362
ResoniteMaterialBinding material = Assert.Single(cityObject.Materials);
363363
Assert.Equal(BundledDefaultMaterialFamilies.FacadeHighriseGlass, material.Family);
364364
Assert.Equal(ResoniteMaterialAssetScope.Common, material.AssetScope);
365-
Assert.Equal(new ResoniteFloat2(1.0 / 6.0, 1.0 / 6.0), material.TextureScale);
366-
Assert.Equal(new ResoniteFloat2(0.0, 0.5 / 6.0), material.TextureOffset);
367-
Assert.Equal(new ResoniteFloat2(0.0, 0.0), cityObject.Mesh.Vertices[0].UV0);
368-
Assert.Equal(new ResoniteFloat2(1.0, 0.0), cityObject.Mesh.Vertices[1].UV0);
369-
Assert.Equal(new ResoniteFloat2(0.0, 1.0), cityObject.Mesh.Vertices[2].UV0);
365+
Assert.Null(material.TextureScale);
366+
Assert.Null(material.TextureOffset);
367+
Assert.Equal(0.0, cityObject.Mesh.Vertices[0].UV0.X, 12);
368+
Assert.Equal(5.0 / 6.0, cityObject.Mesh.Vertices[0].UV0.Y, 12);
369+
Assert.Equal(10.0 / 6.0, cityObject.Mesh.Vertices[1].UV0.X, 12);
370+
Assert.Equal(5.0 / 6.0, cityObject.Mesh.Vertices[1].UV0.Y, 12);
371+
Assert.Equal(0.0, cityObject.Mesh.Vertices[2].UV0.X, 12);
372+
Assert.Equal(15.0 / 6.0, cityObject.Mesh.Vertices[2].UV0.Y, 12);
370373
}
371374

372375
[Fact]
@@ -480,6 +483,8 @@ public async Task FlushAllAsyncKeepsWhitePreservedBundledFamilyMaterialsDedicate
480483
Assert.All(preservedRoofMaterials, static material => Assert.Equal(ResoniteMaterialAssetScope.PresentationSlotScoped, material.AssetScope));
481484
Assert.Contains(preservedRoofMaterials, static material => material.BundledVariantIndex == 0 && material.TextureOffset is null);
482485
Assert.Contains(preservedRoofMaterials, static material => material.BundledVariantIndex == 1 && material.TextureOffset is null);
486+
Assert.NotEqual(new ResoniteFloat2(0.0, 0.0), cityObject.Mesh.Vertices[3].UV0);
487+
Assert.NotEqual(new ResoniteFloat2(0.0, 0.0), cityObject.Mesh.Vertices[6].UV0);
483488
}
484489

485490
[Fact]
@@ -573,8 +578,8 @@ public async Task FlushAllAsyncDemotesPrescopedWhiteBundledFamilyMaterialsWhenOf
573578
Assert.Equal(3, cityObject.Materials.Count);
574579
Assert.Equal(2, preservedRoofMaterials.Length);
575580
Assert.All(preservedRoofMaterials, static material => Assert.Equal(ResoniteMaterialAssetScope.PresentationSlotScoped, material.AssetScope));
576-
Assert.Contains(preservedRoofMaterials, static material => material.BundledVariantIndex == 0 && material.TextureOffset == new ResoniteFloat2(0.125, 0.25));
577-
Assert.Contains(preservedRoofMaterials, static material => material.BundledVariantIndex == 1 && material.TextureOffset == new ResoniteFloat2(0.25, 0.5));
581+
Assert.Contains(preservedRoofMaterials, static material => material.BundledVariantIndex == 0 && material.TextureOffset is null);
582+
Assert.Contains(preservedRoofMaterials, static material => material.BundledVariantIndex == 1 && material.TextureOffset is null);
578583
}
579584

580585
[Fact]

tests/PlateauResoniteLink.Tests/Targets/ResoniteMaterialComponentPolicyTests.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ public void CreateMembersRejectsOffsetOnlyUvTransformBeforeNormalization()
209209
SubmeshIndices: [0],
210210
AssetBinding: ResoniteMaterialAssetBinding.Presentation,
211211
TextureOffset: new ResoniteFloat2(0.125, 0.75),
212-
TerrainOverlayMaterial: new TerrainOverlayMaterialBinding(overlay.MeshCode, overlay),
213-
AssetBinding: ResoniteMaterialAssetBinding.Presentation);
212+
TerrainOverlayMaterial: new TerrainOverlayMaterialBinding(overlay.MeshCode, overlay));
214213

215214
InvalidOperationException error = Assert.Throws<InvalidOperationException>(
216215
() => ResoniteMaterialComponentPolicy.CreateMembers(material));

tests/PlateauResoniteLink.Tests/Targets/ResoniteSceneMaterialConventionsTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ public void NormalizeBatchGroupedMaterialBinding_DemotesTintedBundledFamilyCommo
363363

364364
Assert.Equal(ResoniteMaterialAssetScope.PresentationSlotScoped, normalized.AssetScope);
365365
Assert.Equal(new ResoniteColor(0.8, 0.7, 0.6, 1.0), normalized.BaseColor);
366+
Assert.Null(normalized.TextureScale);
367+
Assert.Null(normalized.TextureOffset);
366368
}
367369

368370
[Fact]
@@ -386,7 +388,8 @@ public void NormalizeBatchGroupedMaterialBinding_DemotesWhiteBundledFamilyCommon
386388

387389
Assert.Equal(ResoniteMaterialAssetScope.PresentationSlotScoped, normalized.AssetScope);
388390
Assert.Equal(new ResoniteMaterialDepthOffset(1.0, 1.0), normalized.DepthOffset);
389-
Assert.Equal(new ResoniteFloat2(0.125, 0.25), normalized.TextureOffset);
391+
Assert.Null(normalized.TextureScale);
392+
Assert.Null(normalized.TextureOffset);
390393
}
391394

392395

0 commit comments

Comments
 (0)