Fix presizing of model location set & use more efficient string generation logic
This commit is contained in:
parent
6979b56d8c
commit
a13587e139
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user