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

Work on re-introducing 3D icon generation

This commit is contained in:
Eclipse
2025-10-16 08:35:57 +00:00
parent 7f67a40c13
commit 535d40c468
8 changed files with 39 additions and 57 deletions

View File

@@ -123,7 +123,7 @@ public class BedrockItemMapper {
bedrockIdentifier = itemModelLocation;
}
BedrockGeometryContext geometry = BedrockGeometryContext.create(bedrockIdentifier, itemModel, context.packContext);
BedrockGeometryContext geometry = BedrockGeometryContext.create(bedrockIdentifier, context.stack, itemModel, context.packContext);
if (context.packContext.reportSuccesses()) {
// Not a problem, but just report to get the model printed in the report file
context.report("creating mapping for block model " + itemModelLocation);

View File

@@ -4,5 +4,7 @@ import org.geysermc.rainbow.mapping.geometry.GeometryRenderer;
import org.geysermc.rainbow.definition.GeyserMappings;
import org.geysermc.rainbow.pack.PackPaths;
import java.util.Optional;
public record PackContext(GeyserMappings mappings, PackPaths paths, BedrockItemConsumer itemConsumer, AssetResolver assetResolver,
GeometryRenderer geometryRenderer, boolean reportSuccesses) {}
Optional<GeometryRenderer> geometryRenderer, boolean reportSuccesses) {}

View File

@@ -5,6 +5,7 @@ import net.minecraft.client.renderer.block.model.TextureSlots;
import net.minecraft.client.resources.model.Material;
import net.minecraft.client.resources.model.ResolvedModel;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import org.geysermc.rainbow.Rainbow;
import org.geysermc.rainbow.mapping.PackContext;
import org.geysermc.rainbow.mapping.animation.AnimationMapper;
@@ -23,7 +24,7 @@ public record BedrockGeometryContext(Optional<Supplier<StitchedGeometry>> geomet
.map(ResourceLocation::withDefaultNamespace)
.toList();
public static BedrockGeometryContext create(ResourceLocation bedrockIdentifier, ResolvedModel model, PackContext context) {
public static BedrockGeometryContext create(ResourceLocation bedrockIdentifier, ItemStack stackToRender, ResolvedModel model, PackContext context) {
ResolvedModel parentModel = model.parent();
// debugName() returns the resource location of the model as a string
boolean handheld = parentModel != null && HANDHELD_MODELS.contains(ResourceLocation.parse(parentModel.debugName()));
@@ -52,7 +53,7 @@ public record BedrockGeometryContext(Optional<Supplier<StitchedGeometry>> geomet
}));
animation = Optional.of(AnimationMapper.mapAnimation(safeIdentifier, "bone", model.getTopTransforms()));
icon = new TextureHolder(modelLocation); // TODO
icon = new TextureHolder(modelLocation, context.geometryRenderer().map(renderer -> () -> renderer.render(stackToRender)));
}
return new BedrockGeometryContext(geometry, animation, icon, handheld);

View File

@@ -1,10 +1,9 @@
package org.geysermc.rainbow.mapping.geometry;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.world.item.ItemStack;
import java.nio.file.Path;
public interface GeometryRenderer {
boolean render(ItemStack stack, Path path);
NativeImage render(ItemStack stack);
}

View File

@@ -1,14 +0,0 @@
package org.geysermc.rainbow.mapping.geometry;
import net.minecraft.world.item.ItemStack;
import java.nio.file.Path;
public class NoopGeometryRenderer implements GeometryRenderer {
public static final NoopGeometryRenderer INSTANCE = new NoopGeometryRenderer();
@Override
public boolean render(ItemStack stack, Path path) {
return false;
}
}

View File

@@ -20,19 +20,21 @@ public record BedrockItem(ResourceLocation identifier, String textureName, Bedro
public CompletableFuture<?> save(PackSerializer serializer, Path attachableDirectory, Path geometryDirectory, Path animationDirectory,
Function<TextureHolder, CompletableFuture<?>> textureSaver) {
return CompletableFuture.supplyAsync(() -> geometryContext.geometry().map(Supplier::get))
.thenCompose(stitchedGeometry -> {
List<TextureHolder> attachableTextures = new ArrayList<>();
Optional<BedrockAttachable> createdAttachable = attachableCreator.create(identifier, stitchedGeometry, attachableTextures::add);
return CompletableFuture.allOf(
textureSaver.apply(geometryContext.icon()),
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()),
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.fileSafeResourceLocation(identifier))).orElse(noop())
);
});
return CompletableFuture.allOf(
textureSaver.apply(geometryContext.icon()),
CompletableFuture.supplyAsync(() -> geometryContext.geometry().map(Supplier::get))
.thenCompose(stitchedGeometry -> {
List<TextureHolder> attachableTextures = new ArrayList<>();
Optional<BedrockAttachable> createdAttachable = attachableCreator.create(identifier, stitchedGeometry, attachableTextures::add);
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()),
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.fileSafeResourceLocation(identifier))).orElse(noop())
);
})
);
}
private static <T> CompletableFuture<T> noop() {

View File

@@ -19,7 +19,6 @@ import org.geysermc.rainbow.mapping.BedrockItemMapper;
import org.geysermc.rainbow.mapping.PackContext;
import org.geysermc.rainbow.mapping.PackSerializer;
import org.geysermc.rainbow.mapping.geometry.GeometryRenderer;
import org.geysermc.rainbow.mapping.geometry.NoopGeometryRenderer;
import org.geysermc.rainbow.definition.GeyserMappings;
import org.geysermc.rainbow.mapping.geometry.TextureHolder;
import org.jetbrains.annotations.NotNull;
@@ -36,6 +35,7 @@ import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class BedrockPack {
@@ -53,7 +53,7 @@ public class BedrockPack {
private final ProblemReporter.Collector reporter;
public BedrockPack(String name, PackManifest manifest, PackPaths paths, PackSerializer serializer, AssetResolver assetResolver,
GeometryRenderer geometryRenderer, ProblemReporter.Collector reporter,
Optional<GeometryRenderer> geometryRenderer, ProblemReporter.Collector reporter,
boolean reportSuccesses) {
this.name = name;
this.manifest = manifest;
@@ -206,7 +206,7 @@ public class BedrockPack {
private UnaryOperator<Path> manifestPath = resolve(MANIFEST_FILE);
private UnaryOperator<Path> itemAtlasPath = resolve(ITEM_ATLAS_FILE);
private Path packZipFile = null;
private GeometryRenderer geometryRenderer = NoopGeometryRenderer.INSTANCE;
private GeometryRenderer geometryRenderer = null;
private ProblemReporter.Collector reporter;
private boolean reportSuccesses = false;
@@ -294,7 +294,7 @@ public class BedrockPack {
PackPaths paths = new PackPaths(mappingsPath, packRootPath, attachablesPath.apply(packRootPath),
geometryPath.apply(packRootPath), animationPath.apply(packRootPath), manifestPath.apply(packRootPath),
itemAtlasPath.apply(packRootPath), Optional.ofNullable(packZipFile));
return new BedrockPack(name, manifest, paths, packSerializer, assetResolver, geometryRenderer, reporter, reportSuccesses);
return new BedrockPack(name, manifest, paths, packSerializer, assetResolver, Optional.ofNullable(geometryRenderer), reporter, reportSuccesses);
}
private static UnaryOperator<Path> resolve(Path child) {