mirror of
https://github.com/GeyserMC/Rainbow.git
synced 2025-12-19 14:59:16 +00:00
Refactors (unfinished), actually generate geometry files
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
package org.geysermc.packgenerator.mapping;
|
||||
|
||||
import org.geysermc.packgenerator.pack.BedrockItem;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BedrockItemConsumer {
|
||||
|
||||
void accept(BedrockItem item);
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
package org.geysermc.packgenerator.mapping.geyser;
|
||||
package org.geysermc.packgenerator.mapping;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.block.model.SimpleUnbakedGeometry;
|
||||
import net.minecraft.client.renderer.item.BlockModelWrapper;
|
||||
import net.minecraft.client.renderer.item.ConditionalItemModel;
|
||||
import net.minecraft.client.renderer.item.ItemModel;
|
||||
@@ -28,27 +29,32 @@ import net.minecraft.world.level.Level;
|
||||
import org.geysermc.packgenerator.accessor.BlockModelWrapperLocationAccessor;
|
||||
import org.geysermc.packgenerator.accessor.ResolvedModelAccessor;
|
||||
import org.geysermc.packgenerator.accessor.SelectItemModelCasesAccessor;
|
||||
import org.geysermc.packgenerator.mapping.attachable.AttachableMapper;
|
||||
import org.geysermc.packgenerator.mapping.geometry.GeometryMapper;
|
||||
import org.geysermc.packgenerator.mapping.geyser.GeyserSingleDefinition;
|
||||
import org.geysermc.packgenerator.mapping.geyser.predicate.GeyserConditionPredicate;
|
||||
import org.geysermc.packgenerator.mapping.geyser.predicate.GeyserMatchPredicate;
|
||||
import org.geysermc.packgenerator.mapping.geyser.predicate.GeyserPredicate;
|
||||
import org.geysermc.packgenerator.mixin.ConditionalItemModelAccessor;
|
||||
import org.geysermc.packgenerator.mixin.SelectItemModelAccessor;
|
||||
import org.geysermc.packgenerator.pack.BedrockItem;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class GeyserItemMapper {
|
||||
public class BedrockItemMapper {
|
||||
private static final List<ResourceLocation> HANDHELD_MODELS = Stream.of("item/handheld", "item/handheld_rod", "item/handheld_mace")
|
||||
.map(ResourceLocation::withDefaultNamespace)
|
||||
.toList();
|
||||
|
||||
public static void mapItem(ResourceLocation modelLocation, String displayName, int protectionValue, DataComponentPatch componentPatch, ProblemReporter reporter,
|
||||
BiConsumer<GeyserSingleDefinition, ResourceLocation> mappingTextureConsumer) {
|
||||
Consumer<GeyserSingleDefinition> mappingConsumer, BedrockItemConsumer itemConsumer, Consumer<ResourceLocation> additionalTextureConsumer) {
|
||||
ItemModel model = Minecraft.getInstance().getModelManager().getItemModel(modelLocation);
|
||||
MappingContext context = new MappingContext(List.of(), modelLocation, displayName, protectionValue, componentPatch, reporter.forChild(() -> "client item definition " + modelLocation + " "), mappingTextureConsumer);
|
||||
MappingContext context = new MappingContext(List.of(), modelLocation, displayName, protectionValue, componentPatch,
|
||||
reporter.forChild(() -> "client item definition " + modelLocation + " "), mappingConsumer, itemConsumer, additionalTextureConsumer);
|
||||
mapItem(model, context);
|
||||
}
|
||||
|
||||
@@ -73,10 +79,13 @@ public class GeyserItemMapper {
|
||||
|
||||
ResourceLocation texture = itemModelLocation;
|
||||
Material layer0Texture = itemModel.getTopTextureSlots().getMaterial("layer0");
|
||||
Optional<SimpleUnbakedGeometry> customGeometry = Optional.empty();
|
||||
if (layer0Texture != null) {
|
||||
texture = layer0Texture.texture();
|
||||
} else {
|
||||
customGeometry = Optional.of((SimpleUnbakedGeometry) itemModel.getTopGeometry());
|
||||
}
|
||||
context.create(bedrockIdentifier, texture, handheld);
|
||||
context.create(bedrockIdentifier, texture, handheld, customGeometry);
|
||||
}, () -> context.reporter.report(() -> "missing block model " + itemModelLocation));
|
||||
}
|
||||
case ConditionalItemModel conditional -> mapConditionalModel(conditional, context.child("condition " + conditional + " "));
|
||||
@@ -131,20 +140,31 @@ public class GeyserItemMapper {
|
||||
}
|
||||
|
||||
private record MappingContext(List<GeyserPredicate> predicateStack, ResourceLocation model, String displayName, int protectionValue, DataComponentPatch componentPatch, ProblemReporter reporter,
|
||||
BiConsumer<GeyserSingleDefinition, ResourceLocation> mappingTextureConsumer) {
|
||||
Consumer<GeyserSingleDefinition> mappingConsumer, BedrockItemConsumer itemConsumer, Consumer<ResourceLocation> additionalTextureConsumer) {
|
||||
|
||||
public MappingContext with(GeyserPredicate predicate, String childName) {
|
||||
return new MappingContext(Stream.concat(predicateStack.stream(), Stream.of(predicate)).toList(), model, displayName, protectionValue, componentPatch,
|
||||
reporter.forChild(() -> childName), mappingTextureConsumer);
|
||||
reporter.forChild(() -> childName), mappingConsumer, itemConsumer, additionalTextureConsumer);
|
||||
}
|
||||
|
||||
public MappingContext child(String childName) {
|
||||
return new MappingContext(predicateStack, model, displayName, protectionValue, componentPatch, reporter.forChild(() -> childName), mappingTextureConsumer);
|
||||
return new MappingContext(predicateStack, model, displayName, protectionValue, componentPatch, reporter.forChild(() -> childName), mappingConsumer, itemConsumer, additionalTextureConsumer);
|
||||
}
|
||||
|
||||
public void create(ResourceLocation bedrockIdentifier, ResourceLocation texture, boolean displayHandheld) {
|
||||
mappingTextureConsumer.accept(new GeyserSingleDefinition(Optional.of(model), bedrockIdentifier, Optional.of(displayName), predicateStack,
|
||||
new GeyserSingleDefinition.BedrockOptions(Optional.empty(), true, displayHandheld, protectionValue), componentPatch), texture);
|
||||
public void create(ResourceLocation bedrockIdentifier, ResourceLocation texture, boolean displayHandheld,
|
||||
Optional<SimpleUnbakedGeometry> customGeometry) {
|
||||
GeyserSingleDefinition definition = new GeyserSingleDefinition(Optional.of(model), bedrockIdentifier, Optional.of(displayName), predicateStack,
|
||||
new GeyserSingleDefinition.BedrockOptions(Optional.empty(), true, displayHandheld, protectionValue), componentPatch);
|
||||
try {
|
||||
mappingConsumer.accept(definition);
|
||||
} catch (Exception exception) {
|
||||
reporter.forChild(() -> "mapping with bedrock identifier " + bedrockIdentifier + " ").report(() -> "failed to pass mapping: " + exception.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
itemConsumer.accept(new BedrockItem(bedrockIdentifier, definition.textureName(), texture,
|
||||
AttachableMapper.mapItem(componentPatch, bedrockIdentifier, additionalTextureConsumer),
|
||||
customGeometry.map(geometry -> GeometryMapper.mapGeometry(definition.textureName(), geometry))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,11 @@ import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.model.EquipmentAssetManager;
|
||||
import net.minecraft.client.resources.model.EquipmentClientInfo;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.equipment.Equippable;
|
||||
import org.geysermc.packgenerator.mixin.EntityRenderDispatcherAccessor;
|
||||
import org.geysermc.packgenerator.pack.attachable.BedrockAttachable;
|
||||
|
||||
@@ -17,9 +18,10 @@ import java.util.function.Consumer;
|
||||
|
||||
public class AttachableMapper {
|
||||
|
||||
public static Optional<BedrockAttachable> mapItem(ItemStack stack, ResourceLocation bedrockIdentifier, Consumer<ResourceLocation> textureConsumer) {
|
||||
public static Optional<BedrockAttachable> mapItem(DataComponentPatch components, ResourceLocation bedrockIdentifier, Consumer<ResourceLocation> textureConsumer) {
|
||||
// Crazy optional statement
|
||||
return Optional.ofNullable(stack.get(DataComponents.EQUIPPABLE))
|
||||
return Optional.ofNullable(components.get(DataComponents.EQUIPPABLE))
|
||||
.flatMap(optional -> (Optional<Equippable>) optional)
|
||||
.flatMap(equippable -> {
|
||||
EquipmentAssetManager equipmentAssets = ((EntityRenderDispatcherAccessor) Minecraft.getInstance().getEntityRenderDispatcher()).getEquipmentAssets();
|
||||
return equippable.assetId().map(asset -> Pair.of(equippable.slot(), equipmentAssets.get(asset)));
|
||||
|
||||
@@ -10,13 +10,15 @@ import net.minecraft.util.ProblemReporter;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.geysermc.packgenerator.CodecUtil;
|
||||
import org.geysermc.packgenerator.mapping.BedrockItemConsumer;
|
||||
import org.geysermc.packgenerator.mapping.BedrockItemMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class GeyserMappings {
|
||||
@@ -73,20 +75,12 @@ public class GeyserMappings {
|
||||
return mappings.size();
|
||||
}
|
||||
|
||||
public void map(ItemStack stack, ResourceLocation model, ProblemReporter reporter, BiConsumer<GeyserSingleDefinition, ResourceLocation> mappingTextureConsumer) {
|
||||
public void map(ItemStack stack, ResourceLocation model, ProblemReporter reporter, BedrockItemConsumer itemConsumer, Consumer<ResourceLocation> additionalTextureConsumer) {
|
||||
String displayName = stack.getHoverName().getString();
|
||||
int protectionValue = 0; // TODO check the attributes
|
||||
|
||||
GeyserItemMapper.mapItem(model, displayName, protectionValue, stack.getComponentsPatch(), reporter,
|
||||
(mapping, texture) -> {
|
||||
try {
|
||||
map(stack.getItemHolder(), mapping);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
reporter.forChild(() -> "mapping with bedrock identifier " + mapping.bedrockIdentifier() + " ").report(() -> "failed to add mapping to mappings file: " + exception.getMessage());
|
||||
return;
|
||||
}
|
||||
mappingTextureConsumer.accept(mapping, texture);
|
||||
});
|
||||
BedrockItemMapper.mapItem(model, displayName, protectionValue, stack.getComponentsPatch(), reporter,
|
||||
mapping -> map(stack.getItemHolder(), mapping), itemConsumer, additionalTextureConsumer);
|
||||
}
|
||||
|
||||
public Map<Holder<Item>, Collection<GeyserMapping>> mappings() {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.geysermc.packgenerator.pack;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.geysermc.packgenerator.pack.attachable.BedrockAttachable;
|
||||
import org.geysermc.packgenerator.pack.geometry.BedrockGeometry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public record BedrockItem(ResourceLocation identifier, String textureName, ResourceLocation texture, Optional<BedrockAttachable> attachable, Optional<BedrockGeometry> geometry) {
|
||||
|
||||
public void save(Path attachableDirectory, Path geometryDirectory) throws IOException {
|
||||
if (attachable.isPresent()) {
|
||||
attachable.get().save(attachableDirectory);
|
||||
}
|
||||
if (geometry.isPresent()) {
|
||||
geometry.get().save(geometryDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,8 @@ import net.minecraft.world.item.ItemStack;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.geysermc.packgenerator.CodecUtil;
|
||||
import org.geysermc.packgenerator.PackConstants;
|
||||
import org.geysermc.packgenerator.mapping.attachable.AttachableMapper;
|
||||
import org.geysermc.packgenerator.mapping.geyser.GeyserMappings;
|
||||
import org.geysermc.packgenerator.mixin.SplashRendererAccessor;
|
||||
import org.geysermc.packgenerator.pack.attachable.BedrockAttachable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
@@ -22,7 +20,6 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -34,6 +31,7 @@ public class BedrockPack {
|
||||
private static final Path EXPORT_DIRECTORY = FabricLoader.getInstance().getGameDir().resolve("geyser");
|
||||
private static final Path PACK_DIRECTORY = Path.of("pack");
|
||||
private static final Path ATTACHABLES_DIRECTORY = Path.of("attachables");
|
||||
private static final Path GEOMETRY_DIRECTORY = Path.of("models/entity");
|
||||
|
||||
private static final Path MAPPINGS_FILE = Path.of("geyser_mappings.json");
|
||||
private static final Path MANIFEST_FILE = Path.of("manifest.json");
|
||||
@@ -47,9 +45,9 @@ public class BedrockPack {
|
||||
private final PackManifest manifest;
|
||||
private final GeyserMappings mappings;
|
||||
private final BedrockTextures.Builder itemTextures;
|
||||
private final List<BedrockAttachable> attachables = new ArrayList<>();
|
||||
private final Set<ResourceLocation> texturesToExport = new HashSet<>();
|
||||
|
||||
private final Set<BedrockItem> bedrockItems = new HashSet<>();
|
||||
private final Set<ResourceLocation> texturesToExport = new HashSet<>();
|
||||
private final Set<ResourceLocation> modelsMapped = new HashSet<>();
|
||||
|
||||
private final ProblemReporter.Collector reporter;
|
||||
@@ -101,11 +99,11 @@ public class BedrockPack {
|
||||
}
|
||||
};
|
||||
|
||||
mappings.map(stack, model, mapReporter, (mapping, texture) -> {
|
||||
itemTextures.withItemTexture(mapping, texture.getPath());
|
||||
texturesToExport.add(texture);
|
||||
AttachableMapper.mapItem(stack, mapping.bedrockIdentifier(), texturesToExport::add).ifPresent(attachables::add);
|
||||
});
|
||||
mappings.map(stack, model, mapReporter, bedrockItem -> {
|
||||
itemTextures.withItemTexture(bedrockItem);
|
||||
texturesToExport.add(bedrockItem.texture());
|
||||
bedrockItems.add(bedrockItem);
|
||||
}, texturesToExport::add);
|
||||
return Optional.of(problems.get());
|
||||
}
|
||||
|
||||
@@ -120,11 +118,11 @@ public class BedrockPack {
|
||||
reporter.forChild(() -> "saving Geyser mappings, pack manifest, and texture atlas ").report(() -> "failed to save to pack: " + exception);
|
||||
success = false;
|
||||
}
|
||||
for (BedrockAttachable attachable : attachables) {
|
||||
for (BedrockItem item : bedrockItems) {
|
||||
try {
|
||||
attachable.save(packPath.resolve(ATTACHABLES_DIRECTORY));
|
||||
item.save(packPath.resolve(ATTACHABLES_DIRECTORY), packPath.resolve(GEOMETRY_DIRECTORY));
|
||||
} catch (IOException exception) {
|
||||
reporter.forChild(() -> "attachable for bedrock item " + attachable.info().identifier() + " ").report(() -> "failed to save to pack: " + exception);
|
||||
reporter.forChild(() -> "files for bedrock item " + item.identifier() + " ").report(() -> "failed to save to pack: " + exception);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +164,7 @@ Textures tried to export: %d
|
||||
-- PROBLEM REPORT --
|
||||
%s
|
||||
""".formatted(randomSummaryComment(), name, mappings.size(), itemTextures.build().size(),
|
||||
attachables.size(), texturesToExport.size(), reporter.getTreeReport());
|
||||
bedrockItems.size(), texturesToExport.size(), reporter.getTreeReport());
|
||||
}
|
||||
|
||||
private static String randomSummaryComment() {
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.geysermc.packgenerator.pack;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import org.geysermc.packgenerator.mapping.geyser.GeyserSingleDefinition;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -33,8 +32,8 @@ public record BedrockTextures(Map<String, String> textures) {
|
||||
public static class Builder {
|
||||
private final Map<String, String> textures = new HashMap<>();
|
||||
|
||||
public Builder withItemTexture(GeyserSingleDefinition mapping, String texturePath) {
|
||||
return withTexture(mapping.textureName(), TEXTURES_FOLDER + texturePath);
|
||||
public Builder withItemTexture(BedrockItem item) {
|
||||
return withTexture(item.textureName(), TEXTURES_FOLDER + item.texture().getPath());
|
||||
}
|
||||
|
||||
public Builder withTexture(String name, String texture) {
|
||||
|
||||
@@ -203,8 +203,8 @@ public record BedrockGeometry(BedrockVersion formatVersion, List<GeometryDefinit
|
||||
private static final Codec<Map<Direction, Face>> FACE_MAP_CODEC = Codec.unboundedMap(Direction.CODEC, Face.CODEC);
|
||||
public static final Codec<Cube> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
ExtraCodecs.VECTOR3F.fieldOf("uvOrigin").forGetter(Cube::origin),
|
||||
ExtraCodecs.VECTOR3F.fieldOf("uvSize").forGetter(Cube::size),
|
||||
ExtraCodecs.VECTOR3F.fieldOf("origin").forGetter(Cube::origin),
|
||||
ExtraCodecs.VECTOR3F.fieldOf("size").forGetter(Cube::size),
|
||||
ExtraCodecs.VECTOR3F.optionalFieldOf("rotation", VECTOR3F_ZERO).forGetter(Cube::size),
|
||||
ExtraCodecs.VECTOR3F.optionalFieldOf("pivot", VECTOR3F_ZERO).forGetter(Cube::pivot),
|
||||
Codec.FLOAT.optionalFieldOf("inflate", 0.0F).forGetter(Cube::inflate),
|
||||
|
||||
Reference in New Issue
Block a user