Wheels are rendered

- Add water wheel rendering
- Use NbtUtils to read block states in CopycatBlockEntity and
WaterWheelBlockEntity
This commit is contained in:
PepperCode1 2023-02-24 18:08:31 -08:00
parent 3756ced16b
commit 9271edf298
11 changed files with 276 additions and 72 deletions

View file

@ -85,6 +85,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul
import com.simibubi.create.content.contraptions.components.turntable.TurntableBlockEntity;
import com.simibubi.create.content.contraptions.components.waterwheel.LargeWaterWheelBlockEntity;
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelBlockEntity;
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelInstance;
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelRenderer;
import com.simibubi.create.content.contraptions.fluids.PumpBlockEntity;
import com.simibubi.create.content.contraptions.fluids.PumpCogInstance;
import com.simibubi.create.content.contraptions.fluids.PumpRenderer;
@ -602,16 +604,16 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<WaterWheelBlockEntity> WATER_WHEEL = REGISTRATE
.blockEntity("water_wheel", WaterWheelBlockEntity::new)
.instance(() -> CutoutRotatingInstance::new, false)
.instance(() -> WaterWheelInstance::standard, false)
.validBlocks(AllBlocks.WATER_WHEEL)
.renderer(() -> KineticBlockEntityRenderer::new)
.renderer(() -> WaterWheelRenderer::standard)
.register();
public static final BlockEntityEntry<LargeWaterWheelBlockEntity> LARGE_WATER_WHEEL = REGISTRATE
.blockEntity("large_water_wheel", LargeWaterWheelBlockEntity::new)
.instance(() -> CutoutRotatingInstance::new, false)
.instance(() -> WaterWheelInstance::large, false)
.validBlocks(AllBlocks.LARGE_WATER_WHEEL)
.renderer(() -> KineticBlockEntityRenderer::new)
.renderer(() -> WaterWheelRenderer::large)
.register();
public static final BlockEntityEntry<MechanicalPressBlockEntity> MECHANICAL_PRESS = REGISTRATE

View file

@ -159,6 +159,11 @@ public class AllPartialModels {
WHISTLE_MOUTH_MEDIUM = block("steam_whistle/medium_mouth"),
WHISTLE_MOUTH_SMALL = block("steam_whistle/small_mouth"),
WATER_WHEEL = block("water_wheel/block"),
WATER_WHEEL_EXTENSION = block("water_wheel/block_extension"),
LARGE_WATER_WHEEL = block("large_water_wheel/block"),
LARGE_WATER_WHEEL_EXTENSION = block("large_water_wheel/block_extension"),
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),

View file

@ -5,6 +5,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.glu
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.TrainHUD;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.contraptions.components.structureMovement.render.SBBContraptionManager;
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelRenderer;
import com.simibubi.create.content.contraptions.goggles.GoggleOverlayRenderer;
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
import com.simibubi.create.content.curiosities.armor.RemainingAirOverlay;
@ -80,6 +81,7 @@ public class CreateClient {
BUFFER_CACHE.registerCompartment(CachedBufferer.PARTIAL);
BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL);
BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK);
BUFFER_CACHE.registerCompartment(WaterWheelRenderer.WATER_WHEEL);
BUFFER_CACHE.registerCompartment(SBBContraptionManager.CONTRAPTION, 20);
BUFFER_CACHE.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20);

View file

@ -10,6 +10,7 @@ public class CutoutRotatingInstance<T extends KineticBlockEntity> extends Single
super(materialManager, blockEntity);
}
@Override
protected Material<RotatingData> getRotatingMaterial() {
return materialManager.defaultCutout()
.material(AllMaterialSpecs.ROTATING);

View file

@ -1,13 +1,11 @@
package com.simibubi.create.content.contraptions.components.waterwheel;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonParser;
import com.mojang.serialization.JsonOps;
import com.simibubi.create.content.contraptions.base.GeneratingKineticBlockEntity;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.foundation.advancement.AllAdvancements;
@ -22,6 +20,7 @@ import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.core.Vec3i;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionResult;
@ -34,14 +33,11 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
public static Map<Axis, Set<BlockPos>> SMALL_OFFSETS = new IdentityHashMap<>();
public static Map<Axis, Set<BlockPos>> LARGE_OFFSETS = new IdentityHashMap<>();
public static final Map<Axis, Set<BlockPos>> SMALL_OFFSETS = new EnumMap<>(Axis.class);
public static final Map<Axis, Set<BlockPos>> LARGE_OFFSETS = new EnumMap<>(Axis.class);
static {
for (Axis axis : Iterate.axes) {
@ -70,11 +66,11 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
}
public int flowScore;
public BlockState baseBlock; // <-- TODO use planks/corresponding logs in rendered instance
public BlockState material;
public WaterWheelBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
baseBlock = Blocks.SPRUCE_PLANKS.defaultBlockState();
material = Blocks.SPRUCE_PLANKS.defaultBlockState();
}
protected int getSize() {
@ -85,15 +81,15 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
return (getSize() == 1 ? SMALL_OFFSETS : LARGE_OFFSETS).get(getAxis());
}
public InteractionResult applyMaterialIfValid(ItemStack item) {
if (!(item.getItem() instanceof BlockItem blockItem))
public InteractionResult applyMaterialIfValid(ItemStack stack) {
if (!(stack.getItem() instanceof BlockItem blockItem))
return InteractionResult.PASS;
BlockState material = blockItem.getBlock().defaultBlockState();
if (material == this.baseBlock)
if (material == this.material)
return InteractionResult.PASS;
if (!material.is(BlockTags.PLANKS))
return InteractionResult.PASS;
baseBlock = material;
this.material = material;
notifyUpdate();
return InteractionResult.SUCCESS;
}
@ -155,30 +151,6 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
setChanged();
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
registerAwardables(behaviours, AllAdvancements.LAVA_WHEEL, AllAdvancements.WATER_WHEEL);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
flowScore = compound.getInt("FlowScore");
BlockState prevMaterial = baseBlock;
if (!compound.contains("Material"))
return;
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.decode(ops, JsonParser.parseString(compound.getString("Material")))
.result()
.ifPresent(p -> baseBlock = p.getFirst());
if (clientPacket && prevMaterial != baseBlock)
redraw();
}
private void redraw() {
if (!isVirtual())
requestModelDataUpdate();
@ -190,23 +162,32 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
}
}
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
registerAwardables(behaviours, AllAdvancements.LAVA_WHEEL, AllAdvancements.WATER_WHEEL);
}
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder().withInitial(MATERIAL_PROPERTY, baseBlock)
.build();
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
flowScore = compound.getInt("FlowScore");
BlockState prevMaterial = material;
if (!compound.contains("Material"))
return;
material = NbtUtils.readBlockState(compound.getCompound("Material"));
if (clientPacket && prevMaterial != material)
redraw();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("FlowScore", flowScore);
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.encode(baseBlock, ops, ops.empty())
.result()
.map(je -> je.toString())
.ifPresent(s -> compound.putString("Material", s));
compound.put("Material", NbtUtils.writeBlockState(material));
}
@Override

View file

@ -1,13 +1,56 @@
package com.simibubi.create.content.contraptions.components.waterwheel;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.model.BlockModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.base.CutoutRotatingInstance;
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
import com.simibubi.create.content.contraptions.base.flwdata.RotatingData;
import com.simibubi.create.foundation.render.CachedBufferer;
public class WaterWheelInstance extends CutoutRotatingInstance {
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
public WaterWheelInstance(MaterialManager modelManager, KineticBlockEntity tile) {
super(modelManager, tile);
public class WaterWheelInstance<T extends WaterWheelBlockEntity> extends CutoutRotatingInstance<T> {
protected final boolean large;
protected final WaterWheelModelKey key;
public WaterWheelInstance(MaterialManager materialManager, T blockEntity, boolean large) {
super(materialManager, blockEntity);
this.large = large;
key = new WaterWheelModelKey(large, getRenderedBlockState(), blockEntity.material);
}
public static <T extends WaterWheelBlockEntity> WaterWheelInstance<T> standard(MaterialManager materialManager, T blockEntity) {
return new WaterWheelInstance<>(materialManager, blockEntity, false);
}
public static <T extends WaterWheelBlockEntity> WaterWheelInstance<T> large(MaterialManager materialManager, T blockEntity) {
return new WaterWheelInstance<>(materialManager, blockEntity, true);
}
@Override
public boolean shouldReset() {
return super.shouldReset() || key.material() != blockEntity.material;
}
@Override
protected Instancer<RotatingData> getModel() {
return getRotatingMaterial().model(key, () -> {
BakedModel model = WaterWheelRenderer.generateModel(key);
BlockState state = key.state();
// TODO waterwheels
Direction dir;
if (key.large()) {
dir = Direction.fromAxisAndDirection(state.getValue(LargeWaterWheelBlock.AXIS), AxisDirection.POSITIVE);
} else {
dir = state.getValue(WaterWheelBlock.FACING);
}
PoseStack transform = CachedBufferer.rotateToFaceVertical(dir).get();
return new BlockModel(model, Blocks.AIR.defaultBlockState(), transform);
});
}
}

View file

@ -0,0 +1,6 @@
package com.simibubi.create.content.contraptions.components.waterwheel;
import net.minecraft.world.level.block.state.BlockState;
public record WaterWheelModelKey(boolean large, BlockState state, BlockState material) {
}

View file

@ -0,0 +1,115 @@
package com.simibubi.create.content.contraptions.components.waterwheel;
import java.util.Map;
import java.util.function.Function;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.StitchedSprite;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.model.BakedModelHelper;
import com.simibubi.create.foundation.render.BakedModelRenderHelper;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache.Compartment;
import com.simibubi.create.foundation.utility.RegisteredObjects;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
public class WaterWheelRenderer<T extends WaterWheelBlockEntity> extends KineticBlockEntityRenderer<T> {
public static final Compartment<WaterWheelModelKey> WATER_WHEEL = new Compartment<>();
public static final StitchedSprite OAK_PLANKS_TEMPLATE = new StitchedSprite(new ResourceLocation("block/oak_planks"));
public static final StitchedSprite OAK_LOG_TEMPLATE = new StitchedSprite(new ResourceLocation("block/oak_log"));
public static final StitchedSprite OAK_LOG_TOP_TEMPLATE = new StitchedSprite(new ResourceLocation("block/oak_log_top"));
protected final boolean large;
public WaterWheelRenderer(Context context, boolean large) {
super(context);
this.large = large;
}
public static <T extends WaterWheelBlockEntity> WaterWheelRenderer<T> standard(Context context) {
return new WaterWheelRenderer<>(context, false);
}
public static <T extends WaterWheelBlockEntity> WaterWheelRenderer<T> large(Context context) {
return new WaterWheelRenderer<>(context, true);
}
@Override
protected SuperByteBuffer getRotatedModel(T be, BlockState state) {
WaterWheelModelKey key = new WaterWheelModelKey(large, state, be.material);
return CreateClient.BUFFER_CACHE.get(WATER_WHEEL, key, () -> {
BakedModel model = WaterWheelRenderer.generateModel(key);
BlockState state1 = key.state();
// TODO waterwheels
Direction dir;
if (key.large()) {
dir = Direction.fromAxisAndDirection(state1.getValue(LargeWaterWheelBlock.AXIS), AxisDirection.POSITIVE);
} else {
dir = state1.getValue(WaterWheelBlock.FACING);
}
PoseStack transform = CachedBufferer.rotateToFaceVertical(dir).get();
return BakedModelRenderHelper.standardModelRender(model, Blocks.AIR.defaultBlockState(), transform);
});
}
public static PartialModel getTemplateModel(boolean large, boolean extension) {
if (large) {
if (extension) {
return AllPartialModels.LARGE_WATER_WHEEL_EXTENSION;
} else {
return AllPartialModels.LARGE_WATER_WHEEL;
}
} else {
if (extension) {
return AllPartialModels.WATER_WHEEL_EXTENSION;
} else {
return AllPartialModels.WATER_WHEEL;
}
}
}
public static BakedModel generateModel(WaterWheelModelKey key) {
// TODO waterwheels
// boolean extension = state.getValue(LargeWaterWheelBlock.EXTENSION);
boolean extension = key.state().getOptionalValue(LargeWaterWheelBlock.EXTENSION).orElse(false);
BakedModel template = getTemplateModel(key.large(), extension).get();
// TODO waterwheels: improve sprite selection
BlockState material = key.material();
Block block = material.getBlock();
ResourceLocation id = RegisteredObjects.getKeyOrThrow(block);
String path = id.getPath();
if (path.endsWith("_planks")) {
String namespace = id.getNamespace();
String wood = path.substring(0, path.length() - 7);
Function<ResourceLocation, TextureAtlasSprite> spriteFunc = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
Map<TextureAtlasSprite, TextureAtlasSprite> map = new Reference2ReferenceOpenHashMap<>();
map.put(OAK_PLANKS_TEMPLATE.get(), spriteFunc.apply(new ResourceLocation(namespace, "block/" + wood + "_planks")));
map.put(OAK_LOG_TEMPLATE.get(), spriteFunc.apply(new ResourceLocation(namespace, "block/" + wood + "_log")));
map.put(OAK_LOG_TOP_TEMPLATE.get(), spriteFunc.apply(new ResourceLocation(namespace, "block/" + wood + "_log_top")));
return BakedModelHelper.generateModel(template, map::get);
}
return BakedModelHelper.generateModel(template, sprite -> null);
}
}

View file

@ -5,7 +5,6 @@ import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftRenderer;
import com.simibubi.create.content.contraptions.relays.gauge.GaugeBlock.Type;
import com.simibubi.create.foundation.render.CachedBufferer;
@ -19,7 +18,7 @@ import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
public class GaugeRenderer extends ShaftRenderer {
public class GaugeRenderer extends ShaftRenderer<GaugeBlockEntity> {
protected GaugeBlock.Type type;
@ -37,7 +36,7 @@ public class GaugeRenderer extends ShaftRenderer {
}
@Override
protected void renderSafe(KineticBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
protected void renderSafe(GaugeBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel())) return;

View file

@ -2,8 +2,6 @@ package com.simibubi.create.content.curiosities.frames;
import java.util.List;
import com.google.gson.JsonParser;
import com.mojang.serialization.JsonOps;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
@ -18,6 +16,7 @@ import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
@ -136,10 +135,7 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
if (!tag.contains("Material"))
return;
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.decode(ops, JsonParser.parseString(tag.getString("Material")))
.result()
.ifPresent(p -> material = p.getFirst());
material = NbtUtils.readBlockState(tag.getCompound("Material"));
if (clientPacket && prevMaterial != material)
redraw();
@ -148,14 +144,8 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
@Override
protected void write(CompoundTag tag, boolean clientPacket) {
super.write(tag, clientPacket);
tag.put("Item", consumedItem.serializeNBT());
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.encode(material, ops, ops.empty())
.result()
.map(je -> je.toString())
.ifPresent(s -> tag.putString("Material", s));
tag.put("Material", NbtUtils.writeBlockState(material));
}
@Override

View file

@ -3,12 +3,25 @@ package com.simibubi.create.foundation.model;
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU;
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.UnaryOperator;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.ItemOverrides;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.SimpleBakedModel;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.model.data.EmptyModelData;
public class BakedModelHelper {
public static void cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
@ -79,4 +92,51 @@ public class BakedModelHelper {
BakedQuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
}
}
public static BakedModel generateModel(BakedModel template, UnaryOperator<TextureAtlasSprite> spriteSwapper) {
Random random = new Random();
Map<Direction, List<BakedQuad>> culledFaces = new EnumMap<>(Direction.class);
for (Direction cullFace : Iterate.directions) {
random.setSeed(42L);
List<BakedQuad> quads = template.getQuads(null, cullFace, random, EmptyModelData.INSTANCE);
culledFaces.put(cullFace, swapSprites(quads, spriteSwapper));
}
random.setSeed(42L);
List<BakedQuad> quads = template.getQuads(null, null, random, EmptyModelData.INSTANCE);
List<BakedQuad> unculledFaces = swapSprites(quads, spriteSwapper);
TextureAtlasSprite particleSprite = template.getParticleIcon(EmptyModelData.INSTANCE);
TextureAtlasSprite swappedParticleSprite = spriteSwapper.apply(particleSprite);
if (swappedParticleSprite != null) {
particleSprite = swappedParticleSprite;
}
return new SimpleBakedModel(unculledFaces, culledFaces, template.useAmbientOcclusion(), template.usesBlockLight(), template.isGui3d(), particleSprite, template.getTransforms(), ItemOverrides.EMPTY);
}
public static List<BakedQuad> swapSprites(List<BakedQuad> quads, UnaryOperator<TextureAtlasSprite> spriteSwapper) {
List<BakedQuad> newQuads = new ArrayList<>(quads);
int size = quads.size();
for (int i = 0; i < size; i++) {
BakedQuad quad = quads.get(i);
TextureAtlasSprite sprite = quad.getSprite();
TextureAtlasSprite newSprite = spriteSwapper.apply(sprite);
if (newSprite == null || sprite == newSprite)
continue;
BakedQuad newQuad = BakedQuadHelper.clone(quad);
int[] vertexData = newQuad.getVertices();
for (int vertex = 0; vertex < 4; vertex++) {
float u = BakedQuadHelper.getU(vertexData, vertex);
float v = BakedQuadHelper.getV(vertexData, vertex);
BakedQuadHelper.setU(vertexData, vertex, newSprite.getU(getUnInterpolatedU(sprite, u)));
BakedQuadHelper.setV(vertexData, vertex, newSprite.getV(getUnInterpolatedV(sprite, v)));
}
newQuads.set(i, newQuad);
}
return newQuads;
}
}