Fix presizing of model location set & use more efficient string generation logic

This commit is contained in:
embeddedt 2025-05-18 21:55:51 -04:00
parent 6979b56d8c
commit a13587e139
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
2 changed files with 68 additions and 8 deletions

View File

@ -6,14 +6,11 @@ import com.google.common.collect.Sets;
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.MutableGraph;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import net.minecraft.client.renderer.block.BlockModelShaper;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.forgespi.language.IModInfo;
@ -60,13 +57,15 @@ public class ModelBakeEventHelper {
private final MutableGraph<String> dependencyGraph;
public ModelBakeEventHelper(Map<ResourceLocation, BakedModel> modelRegistry) {
this.modelRegistry = modelRegistry;
this.topLevelModelLocations = new ObjectLinkedOpenHashSet<>(Block.BLOCK_STATE_REGISTRY.size() + BuiltInRegistries.ITEM.size());
// Skip going through ModelLocationCache because most of the accesses will be misses
int blockStateCount = 0;
for (var b : BuiltInRegistries.BLOCK) {
blockStateCount += b.getStateDefinition().getPossibleStates().size();
}
this.topLevelModelLocations = new ObjectLinkedOpenHashSet<>(blockStateCount + BuiltInRegistries.ITEM.size());
var modelLocationBuilder = new ModelLocationBuilder();
BuiltInRegistries.BLOCK.entrySet().forEach(entry -> {
var location = entry.getKey().location();
for(BlockState state : entry.getValue().getStateDefinition().getPossibleStates()) {
topLevelModelLocations.add(BlockModelShaper.stateToModelLocation(location, state));
}
modelLocationBuilder.generateForBlock(topLevelModelLocations, entry.getValue(), location);
});
BuiltInRegistries.ITEM.keySet().forEach(key -> topLevelModelLocations.add(new ModelResourceLocation(key, "inventory")));
this.topLevelModelLocations.addAll(modelRegistry.keySet());

View File

@ -0,0 +1,61 @@
package org.embeddedt.modernfix.forge.dynresources;
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.Property;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ModelLocationBuilder {
private final Object2ObjectOpenHashMap<Property<?>, PropertyData> propertyToOptionStrings = new Object2ObjectOpenHashMap<>();
private final StringBuilder builder = new StringBuilder();
private record PropertyData(List<String> nameValuePairs, int maxPairLength) {}
public void generateForBlock(Set<ResourceLocation> destinationSet, Block block, ResourceLocation baseLocation) {
var props = block.getStateDefinition().getProperties();
List<List<String>> optionsList = new ArrayList<>();
int requiredBuilderSize = Math.max(0, props.size() - 1); // commas
for (var prop : props) {
var data = propertyToOptionStrings.computeIfAbsent(prop, ModelLocationBuilder::computePropertyOptions);
optionsList.add(data.nameValuePairs);
requiredBuilderSize += data.maxPairLength;
}
var product = Lists.cartesianProduct(optionsList);
int count = product.size();
int tupleEntryCount = optionsList.size();
StringBuilder stringbuilder = this.builder;
stringbuilder.ensureCapacity(requiredBuilderSize);
for (int i = 0; i < count; i++) {
stringbuilder.setLength(0);
var result = product.get(i);
for (int j = 0; j < tupleEntryCount; j++) {
if (j != 0) {
stringbuilder.append(',');
}
stringbuilder.append(result.get(j));
}
destinationSet.add(new ModelResourceLocation(baseLocation, stringbuilder.toString()));
}
}
private static PropertyData computePropertyOptions(Property<?> prop) {
List<String> valuesList = new ArrayList<>(prop.getPossibleValues().size());
int maxLength = 0;
for (var val : prop.getPossibleValues()) {
String pair = prop.getName() + "=" + getValueName(prop, val);
valuesList.add(pair);
maxLength = Math.max(pair.length(), maxLength);
}
return new PropertyData(List.copyOf(valuesList), maxLength);
}
private static <T extends Comparable<T>> String getValueName(Property<T> property, Comparable<?> value) {
return property.getName((T)value);
}
}