1
0
mirror of https://github.com/GeyserMC/Rainbow.git synced 2025-12-19 14:59:16 +00:00

Properly multiply UV in GeometryMapper, use the right stitched texture in attachables

This commit is contained in:
Eclipse
2025-10-16 09:18:34 +00:00
parent e95e922537
commit 97af13e3bd
9 changed files with 31 additions and 17 deletions

View File

@@ -10,6 +10,7 @@ import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.equipment.Equippable;
import org.geysermc.rainbow.mapping.AssetResolver;
import org.geysermc.rainbow.mapping.geometry.BedrockGeometryContext;
import org.geysermc.rainbow.mapping.geometry.StitchedGeometry;
import org.geysermc.rainbow.mapping.geometry.TextureHolder;
import org.geysermc.rainbow.pack.attachable.BedrockAttachable;
@@ -23,8 +24,7 @@ public class AttachableMapper {
// Crazy optional statement
// Unfortunately we can't have both equippables and custom models, so we prefer the latter :(
return (bedrockIdentifier, stitchedGeometry, textureConsumer) -> stitchedGeometry
.map(BedrockGeometryContext.StitchedGeometry::geometry)
.map(geometry -> BedrockAttachable.geometry(bedrockIdentifier, geometry.definitions().getFirst(), geometryContext.icon().location().getPath()))
.map(stitched -> BedrockAttachable.geometry(bedrockIdentifier, stitched.geometry().definitions().getFirst(), stitched.stitchedTextures().location().getPath()))
.or(() -> Optional.ofNullable(components.get(DataComponents.EQUIPPABLE))
.flatMap(optional -> (Optional<Equippable>) optional)
.flatMap(equippable -> equippable.assetId().flatMap(assetResolver::getEquipmentInfo).map(info -> Pair.of(equippable.slot(), info)))
@@ -59,6 +59,6 @@ public class AttachableMapper {
@FunctionalInterface
public interface AttachableCreator {
Optional<BedrockAttachable> create(ResourceLocation bedrockIdentifier, Optional<BedrockGeometryContext.StitchedGeometry> geometry, Consumer<TextureHolder> textureConsumer);
Optional<BedrockAttachable> create(ResourceLocation bedrockIdentifier, Optional<StitchedGeometry> geometry, Consumer<TextureHolder> textureConsumer);
}
}

View File

@@ -58,6 +58,4 @@ public record BedrockGeometryContext(Optional<Supplier<StitchedGeometry>> geomet
return new BedrockGeometryContext(geometry, animation, icon, handheld);
}
public record StitchedGeometry(BedrockGeometry geometry, TextureHolder stitchedTextures) {}
}

View File

@@ -81,8 +81,15 @@ public class GeometryMapper {
uvSize = new Vector2f(uvs.maxU() - uvs.minU(), uvs.maxV() - uvs.minV());
}
// If the texture was stitched (which it should have been, unless it doesn't exist), offset the UVs by the texture's starting UV
textures.getSprite(face.texture()).ifPresent(sprite -> uvOrigin.add(sprite.getX(), sprite.getY()));
// If the texture was stitched (which it should have been, unless it doesn't exist), s UV values on Java are always in the [0;16] range, adjust the values properly to the texture size,
// and offset the UVs by the texture's starting UV
textures.getSprite(face.texture()).ifPresent(sprite -> {
float widthMultiplier = sprite.contents().width() / 16.0F;
float heightMultiplier = sprite.contents().height() / 16.0F;
uvOrigin.mul(widthMultiplier, heightMultiplier);
uvSize.mul(widthMultiplier, heightMultiplier);
uvOrigin.add(sprite.getX(), sprite.getY());
});
builder.withFace(direction, uvOrigin, uvSize, face.rotation());
}

View File

@@ -0,0 +1,5 @@
package org.geysermc.rainbow.mapping.geometry;
import org.geysermc.rainbow.pack.geometry.BedrockGeometry;
public record StitchedGeometry(BedrockGeometry geometry, TextureHolder stitchedTextures) {}

View File

@@ -5,6 +5,7 @@ import org.geysermc.rainbow.Rainbow;
import org.geysermc.rainbow.mapping.PackSerializer;
import org.geysermc.rainbow.mapping.attachable.AttachableMapper;
import org.geysermc.rainbow.mapping.geometry.BedrockGeometryContext;
import org.geysermc.rainbow.mapping.geometry.StitchedGeometry;
import org.geysermc.rainbow.mapping.geometry.TextureHolder;
import org.geysermc.rainbow.pack.attachable.BedrockAttachable;
@@ -29,8 +30,8 @@ public record BedrockItem(ResourceLocation identifier, String textureName, Bedro
return CompletableFuture.allOf(
createdAttachable.map(attachable -> attachable.save(serializer, attachableDirectory)).orElse(noop()),
CompletableFuture.allOf(attachableTextures.stream().map(textureSaver).toArray(CompletableFuture[]::new)),
stitchedGeometry.map(BedrockGeometryContext.StitchedGeometry::geometry).map(geometry -> geometry.save(serializer, geometryDirectory)).orElse(noop()),
stitchedGeometry.map(BedrockGeometryContext.StitchedGeometry::stitchedTextures).map(textureSaver).orElse(noop()),
stitchedGeometry.map(StitchedGeometry::geometry).map(geometry -> geometry.save(serializer, geometryDirectory)).orElse(noop()),
stitchedGeometry.map(StitchedGeometry::stitchedTextures).map(textureSaver).orElse(noop()),
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.fileSafeResourceLocation(identifier))).orElse(noop())
);
})

View File

@@ -308,8 +308,7 @@ public class BedrockPack {
}
private static PackManifest defaultManifest(String name) {
return new PackManifest(new PackManifest.Header(name, PackConstants.DEFAULT_PACK_DESCRIPTION, UUID.randomUUID(), BedrockVersion.of(0), PackConstants.ENGINE_VERSION),
List.of(new PackManifest.Module(name, PackConstants.DEFAULT_PACK_DESCRIPTION, UUID.randomUUID(), BedrockVersion.of(0))));
return PackManifest.create(name, PackConstants.DEFAULT_PACK_DESCRIPTION, UUID.randomUUID(), BedrockVersion.of(0));
}
}

View File

@@ -5,6 +5,7 @@ import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.UUIDUtil;
import org.geysermc.rainbow.CodecUtil;
import org.geysermc.rainbow.PackConstants;
import java.util.List;
import java.util.UUID;
@@ -56,5 +57,10 @@ public record PackManifest(Header header, List<Module> modules) {
return new Module(name, description, uuid, version.increment());
}
}
public static PackManifest create(String name, String description, UUID uuid, BedrockVersion version) {
return new PackManifest(new PackManifest.Header(name, description, uuid, version, PackConstants.ENGINE_VERSION),
List.of(new PackManifest.Module(name, description, uuid, version)));
}
}

View File

@@ -4,6 +4,7 @@
"package": "org.geysermc.rainbow.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"FaceBakeryAccessor",
"LateBoundIdMapperAccessor",
"NativeImageAccessor",
"RangeSelectItemModelAccessor",
@@ -13,8 +14,5 @@
],
"injectors": {
"defaultRequire": 1
},
"mixins": [
"FaceBakeryAccessor"
]
}
}