diff --git a/src/main/java/org/osm2world/core/target/common/texcoord/TexCoordUtil.java b/src/main/java/org/osm2world/core/target/common/texcoord/TexCoordUtil.java index fb29f7658..23426133d 100644 --- a/src/main/java/org/osm2world/core/target/common/texcoord/TexCoordUtil.java +++ b/src/main/java/org/osm2world/core/target/common/texcoord/TexCoordUtil.java @@ -125,7 +125,7 @@ public static final Function mirroredHo * modifies a calculated texture coordinate to account for {@link TextureDataDimensions#padding()}. * This is helpful when implementing {@link TexCoordFunction}s, not when using them. */ - static VectorXZ applyPadding(VectorXZ texCoord, TextureDataDimensions dimensions) { + public static VectorXZ applyPadding(VectorXZ texCoord, TextureDataDimensions dimensions) { double padding = dimensions.padding(); if (padding == 0) { return texCoord; diff --git a/src/main/java/org/osm2world/core/world/modules/SportsModule.java b/src/main/java/org/osm2world/core/world/modules/SportsModule.java index 8448ba67f..f44503ce4 100644 --- a/src/main/java/org/osm2world/core/world/modules/SportsModule.java +++ b/src/main/java/org/osm2world/core/world/modules/SportsModule.java @@ -21,6 +21,8 @@ import org.osm2world.core.math.VectorXYZ; import org.osm2world.core.math.VectorXZ; import org.osm2world.core.target.common.material.Material; +import org.osm2world.core.target.common.material.TextureDataDimensions; +import org.osm2world.core.target.common.material.TextureLayer; import org.osm2world.core.target.common.mesh.ExtrusionGeometry; import org.osm2world.core.target.common.mesh.LevelOfDetail; import org.osm2world.core.target.common.mesh.Mesh; @@ -29,6 +31,7 @@ import org.osm2world.core.target.common.model.ModelInstance; import org.osm2world.core.target.common.texcoord.NamedTexCoordFunction; import org.osm2world.core.target.common.texcoord.TexCoordFunction; +import org.osm2world.core.target.common.texcoord.TexCoordUtil; import org.osm2world.core.world.data.AbstractAreaWorldObject; import org.osm2world.core.world.data.ProceduralWorldObject; import org.osm2world.core.world.data.TerrainBoundaryWorldObject; @@ -97,7 +100,8 @@ public void buildMeshesAndModels(Target target) { List triangles = getTriangulation(); - TexCoordFunction texFunction = configureTexFunction(area.getOuterPolygon()); + List layers = getPitchMaterial().getTextureLayers(); + TexCoordFunction texFunction = configureTexFunction(area.getOuterPolygon(), layers.get(layers.size() - 1).baseColorTexture.dimensions()); if (texFunction != null) { @@ -124,7 +128,8 @@ public void buildMeshesAndModels(Target target) { * @return the texture coordinate function; * null if it's not possible to construct a valid pitch */ - protected PitchTexFunction configureTexFunction(SimplePolygonXZ polygon) { + protected PitchTexFunction configureTexFunction(SimplePolygonXZ polygon, + TextureDataDimensions textureDimensions) { /* approximate a rectangular shape for the pitch */ @@ -173,7 +178,7 @@ protected PitchTexFunction configureTexFunction(SimplePolygonXZ polygon) { /* build the result */ - return new PitchTexFunction(origin, longSide, shortSide); + return new PitchTexFunction(origin, longSide, shortSide, textureDimensions); } @@ -185,12 +190,15 @@ static class PitchTexFunction implements TexCoordFunction { private final VectorXZ origin; private final VectorXZ longSide; private final VectorXZ shortSide; + private final TextureDataDimensions textureDimensions; - PitchTexFunction(VectorXZ origin, VectorXZ longSide, VectorXZ shortSide) { + PitchTexFunction(VectorXZ origin, VectorXZ longSide, VectorXZ shortSide, + TextureDataDimensions textureDimensions) { this.origin = origin; this.longSide = longSide; this.shortSide = shortSide; + this.textureDimensions = textureDimensions; } @@ -221,9 +229,11 @@ public List apply(List vs) { double angleShort = VectorXZ.angleBetween(v, shortSide); double shortSideProjectedLength = v.length() * cos(angleShort); - result.add(new VectorXZ( - shortSideProjectedLength / shortSide.length(), - longSideProjectedLength / longSide.length())); + VectorXZ rawTexCoord = new VectorXZ( + shortSideProjectedLength / shortSide.length(), + longSideProjectedLength / longSide.length()); + + result.add(TexCoordUtil.applyPadding(rawTexCoord, textureDimensions)); } @@ -363,7 +373,8 @@ public void buildMeshesAndModels(Target target) { /* add a net with posts */ - PitchTexFunction texFunction = configureTexFunction(area.getOuterPolygon()); + List layers = getPitchMaterial().getTextureLayers(); + PitchTexFunction texFunction = configureTexFunction(area.getOuterPolygon(), layers.get(layers.size() - 1).baseColorTexture.dimensions()); //TODO: support this feature when elevation is enabled diff --git a/src/test/java/org/osm2world/core/world/modules/SportsModuleTest.java b/src/test/java/org/osm2world/core/world/modules/SportsModuleTest.java index c3bb86867..b43d7df6e 100644 --- a/src/test/java/org/osm2world/core/world/modules/SportsModuleTest.java +++ b/src/test/java/org/osm2world/core/world/modules/SportsModuleTest.java @@ -7,6 +7,7 @@ import org.junit.Test; import org.osm2world.core.math.VectorXYZ; import org.osm2world.core.math.VectorXZ; +import org.osm2world.core.target.common.material.TextureDataDimensions; import org.osm2world.core.world.modules.SportsModule.Pitch.PitchTexFunction; @@ -16,7 +17,7 @@ public class SportsModuleTest { public void testPitchTexFunction() { PitchTexFunction texFunction = new PitchTexFunction( - NULL_VECTOR, new VectorXZ(2, 0), new VectorXZ(0, 1)); + NULL_VECTOR, new VectorXZ(2, 0), new VectorXZ(0, 1), new TextureDataDimensions(1, 1)); assertAlmostEquals(0, 0, texFunction.apply(asList(new VectorXYZ(0, 0, 0))).get(0)); assertAlmostEquals(0, 1, texFunction.apply(asList(new VectorXYZ(2, 0, 0))).get(0)); @@ -26,7 +27,7 @@ public void testPitchTexFunction() { assertAlmostEquals(2, 2, texFunction.apply(asList(new VectorXYZ(4, 0, 2))).get(0)); assertAlmostEquals(0, -1, texFunction.apply(asList(new VectorXYZ(-2, 0, 0))).get(0)); - texFunction = new PitchTexFunction(NULL_VECTOR, new VectorXZ(0, -3), new VectorXZ(2, 0)); + texFunction = new PitchTexFunction(NULL_VECTOR, new VectorXZ(0, -3), new VectorXZ(2, 0), new TextureDataDimensions(1, 1)); assertAlmostEquals(0, 0, texFunction.apply(asList(new VectorXYZ(0, 0, 0))).get(0)); assertAlmostEquals(0, 1, texFunction.apply(asList(new VectorXYZ(0, 0, -3))).get(0));